Criando extensões para o Firefox - Parte I
28 de Agosto de 2006
Todo mundo já teve uma idéia ou sentiu falta de algum recurso em um programa. No caso de navegadores, é muito fácil adicionar funcionalidades, pelo menos para quem usa Mozilla.
O Mozilla permite adicionar, remover ou alterar funcionalidades utilizando apenas Javascript, CSS e XML. Isso te dá flexibilidade suficiente para fazer absolutamente tudo o que você quiser. Neste artigo, você terá uma idéia de como fazer sua própria extensão utilizando recursos como requisições remotas (XMLHttpRequest), suporte a múltiplos idiomas e configurações (about:config).
Mas o que é uma extensão, afinal?
Uma extensão nada mais é do que um série de arquivos escritos em XUL, Javascript e CSS e compactados em formato ZIP, com a extensão xpi. Veja, por exemplo, como é a estrutura da extensão webdeveloper, de Chris Pederick.

Você pode ou não compactar sua estrutura em formato JAR, a exemplo da extensão Webdeveloper. Neste artigo, não iremos compactá-la.
Toda a interface de sua extensão será feita com tags em XML. Por exemplo, para adicionar um botão você pode utilizar a tag <button />.
Já o comportamento que sua extensão terá é definido com Javascript. Por exemplo, podemos exibir uma mensagem "Você clicou no botão" com o código <button oncommand="alert('Você clicou no botão');" />.
Percebeu que tudo é feito de maneira clara e simples?
Preparando o ambiente para desenvolvimento
Para começar a desenvolver, podemos instalar algumas extensões que irão facilitar nossa vida:
- Console2: exibe os erros no chrome de maneira organizada;
- DOM Inspector: visualizador da estrutura DOM; ajuda na hora de analisarmos o documento;
- ReloadChromezilla: atualiza o chrome sem a necessidade de reiniciar o browser.
Além disso, devemos definir algumas configurações do navegador. Basta digitar about:config como URI na barra de endereços. Se não sabe do que estou falando, dê uma olhada aqui e aqui.
javascript.options.showInConsole: defina como true para exibir os erros de chrome no console;nglayout.debug.disable_xul_cache: defina como true para desabilitar o cache dos arquivos XUL;
Uma coisa extremamente útil é trabalhar com dois perfis distintos. O Firefox não permite que mais de um perfil seja aberto por padrão, mas é possível abrir quantos você quiser. Basta digitar set MOZ_NO_REMOTE=1 na linha de comando. Depois, abra o perfil com o comando firefox -P dev (se for fazer uma extensão para o Thunderbird, é aconselhável que você faça isso). Para usuários de Windows, adicione a pasta do Firefox na variável de ambiente PATH. Veja mais sobre como fazer isso aqui.
Arquivos de Configuração
Para permitir que sua extensão seja instalada, é preciso configurar dois arquivos com algumas informações. São eles chrome.manifest e install.rdf.
Entendendo o "Install Manifest"
O install.rdf é um arquivo XML que contém informações que são utilizadas pelo instalador no momento em que você for adicionar a extensão. Veja um exemplo:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>{XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</em:id>
<em:name>Extensão de Exemplo</em:name>
<em:version>1.0</em:version>
<em:description>Uma extensão de exemplo com algumas funcionalidades</em:description>
<em:creator>Seu nome aqui</em:creator>
<em:contributor>Uma pessoa que te ajudou</em:contributor>
<em:contributor>Outra pessoa</em:contributor>
<em:homepageURL>http://sampleextension.mozdev.org/</em:homepageURL>
<em:optionsURL>chrome://sampleext/content/settings.xul</em:optionsURL>
<em:aboutURL>chrome://sampleext/content/about.xul</em:aboutURL>
<em:iconURL>chrome://sampleext/skin/mainicon.png</em:iconURL>
<em:updateURL>http://sampleextension.mozdev.org/update.rdf</em:updateURL>
<em:type>2</em:type>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>0.9</em:minVersion>
<em:maxVersion>1.0</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
Os pricipais elementos deste arquivo são:
- id
- Obrigatório. Identificador único de sua extensão. Atualmente, somente duas maneiras são aceitas. A primeira é gerando um ID com uma ferramenta desenvolvida pela Microsoft e disponibilizada aqui. Você também pode gerá-la aqui e aqui. A segunda é utilizando o formato extensao@dominio, por exemplo,
extensao@simplesideias.com.br. - name
- Obrigatório. É o nome de sua extensão, por exemplo, "GMail Notifier".
- version
-
Obrigatório. Versão de sua extensão. Se você não em idéia de como definir a versão de sua extensão, use algo como X.Y.Z, onde:
- X denota a versão da extensão
- Y denota implementação de funcionalidades
- Z denota correções de bugs
Na prática, fica algo assim:
- 1.0: versão inicial da extensão;
- 1.0.1: correção de algum bug ou modificação não-significativa;
- 1.1: implementação de nova funcionalidade ou modificação significativa;
- 1.1.1: correção de bug ou modificação não-significativa;
- description
- Obrigatório. Uma descrição de sua extensão, expressa de maneira suscinta.
- creator
- Obrigatório. Nome do criador da extensão.
- homepageURL
- Opcional. Site onde o usuário pode encontrar mais informações sobre a extensão.
- optionsURL
- Opcional. Arquivo que será exibido quando o usuário selecionar a opção "Preferências" da extensão o gerenciador de extensões.
- updateURL
- Opcional. Caminho para atualizações da extensão. Veja um exemplo deste arquivo:
<?xml version="1.0"?> <r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.mozilla.org/2004/em-rdf#"> <r:Description about="urn:mozilla:extension: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"> <updates> <r:Seq> <r:li> <r:Description> <version>0.1</version> <targetApplication> <r:Description> <id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</id> <minVersion>0.8</minVersion> <maxVersion>1.9</maxVersion> <updateLink>http://www.webserver.com/foowidget.xpi</updateLink> </r:Description> </targetApplication> </r:Description> </r:li> </r:Seq> </updates> <version>0.1</version> <updateLink>http://www.webserver.com/foowidget.xpi</updateLink> </r:Description> </r:RDF> - targetApplication
-
Obrigatório. Identifica quais aplicativos sua extensão suporta. Veja algumas GUIDs:
Relação de GUIDs Aplicativo GUID Firefox {ec8030f7-c20a-464f-9b0e-13a3a9e97384} Thunderbird {3550f703-e582-4d05-9a08-453d09bdfdc6} Mozilla Suite {86c18b42-e466-45a9-ae7a-9b95ba6f5640} SeaMonkey {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} Netscape {3db10fab-e461-4c80-8b97-957ad5f8ea47} Flock {a463f10c-3994-11da-9945-000d60ca027b}
Para que sua extensão suporte o Mozilla Suite e SeaMonkey, é preciso incluir no pacote o arquivo install.js. Futuramente, não será mais preciso incluí-lo.
Entendendo o "Chrome Manifest"
Chrome é o nome dado à interface de pacotes criada pelos navegadores Mozilla. Para acessar arquivos adicionados ao Chrome, basta definir a URI chrome://. Um pacote padrão pode ser acessado através da URI chrome://browser/. Para que nossa extensão seja considerada parte do Chrome, é preciso criar um arquivo chamado "Chrome Manifest".
O "Chrome Manifest" é responsável por indicar a localização dos arquivos utilizados por sua extensão. Esse arquivo tem um formato que deve ser seguido e deve estar localizado na raíz da extensão sob o nome chrome.manifest. Veja um exemplo:
content pacote content/
locale pacote pt-BR locale/pt-BR/
locale pacote en-US locale/en-US/
overlay chrome://browser/content/browser.xul chrome://pacote/content/browser.xul
As linhas acima indicam o conteúdo da extensão pacote está no diretório content; possui dois idiomas (pt-BR e en-US) e seus arquivos estão localizados no diretório locale; o arquivo que irá exibir nossa extensão no browser é indicado como overlay.
Apesar do suporte à múltiplos idiomas não ser obrigatório, é extremamente recomendado que você o faça. É muito simples e permite que ela seja utilizada por um maior número de pessoas no mundo!
De olho no câmbio
Nada melhor do que a prática para entender como se faz uma extensão. É recomendado que você tenha conhecimentos de Javascript e CSS, já que estes não serão explicados passo-a-passo. Se você não entende nada desses dois itens, existe bastante coisa disponível por aí!
Nós iremos criar uma extensão que exibe informações sobre o câmbio, com dados disponibilizados pelo site WebServiceX. Para definirmos melhor o que temos que fazer, segue uma lista:
- A extensão atualizará as informações sobre o câmbio em intervalos de 180 segundos;
- Ao clicar o botão esquerdo do mouse, atualizaremos as informações instaneamente;
- Ao clicar com o botão direito, abriremos uma janela de preferências para que seja feita a escolha das moedas para a conversão.
- As moedas escolhidas deverão ser armazenadas de forma que o usuário não precise selecioná-las novamente;
- Nossa extensão terá a seguinte aparência:

- As moedas disponíveis para fazer a conversão são Real, Dólar Americano, Euro, Yen, Yuan, Peso Argentino e Libra Esterlina. Os dados serão obtidos através de uma requisição com o objeto
XMLHttpRequest, popularmente chamado de AJAX.
Criando nossos arquivos de configuração
Para iniciar crie um diretório com o nome "exchangenotifier". Esse será nosso diretório-raiz e também o nome de nosso pacote (daqui para frente referenciado como "raíz", certo?). Crie um arquivo com o nome "install.rdf" e adicione o seguinte conteúdo:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>exchangenotifier@simplesideias.com.br</em:id>
<em:name>Exchange Notifier</em:name>
<em:version>1.0</em:version>
<em:description>Money exchange. Information powered by WebserviceX</em:description>
<em:creator>Nando Vieira</em:creator>
<em:homepageURL>http://simplesideias.com.br/</em:homepageURL>
<em:optionsURL>chrome://exchangenotifier/content/settings.xul</em:optionsURL>
<em:type>2</em:type>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>0.9</em:minVersion>
<em:maxVersion>2+</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
Não se preocupe em colocar a descrição em português. Na segunda parte deste artigo iremos adicionar suporte a múltiplos idiomas.
Agora, criar nosso arquivo "Chrome Manifest"; crie na raíz um arquivo chamado "chrome.manifest" com o seguinte conteúdo:
content exchangenotifier content/
overlay chrome://browser/content/browser.xul chrome://exchangenotifier/content/browser.xul
Novamente, temos a definição do arquivos que compoem nossa extensão. Vale lembrar que não precisamos definir individualmente cada arquivo. Isso poderia ser maçante no caso de termos uma quantidade muito grande de arquivos como imagens. Bastou definir o diretório (neste caso "content").
Como nossa extensão terá algumas configurações que deverão ser salvas (moedas de conversão, por exemplo), já podemos adicioná-las automaticamente durante o processo de instalação, com valores-padrão. Crie um diretório "default" na raíz com um subdiretório "preferences". Um arquivo .js adicionará estas configurações:
pref('extensions.exchangenotifier.from', '');
pref('extensions.exchangenotifier.to', '');
pref('extensions.exchangenotifier.last_exchange', '');
pref('extensions.exchangenotifier.last_status', '');
Agora, crie um diretório na raíz chamado "content". Veja como está nossa estrutura:

Nosso primeiro arquivo XUL
O arquivo "browser.xul" relacionando no Chrome Manifest irá sobrepor (overlay) a interface do browser. Para indicarmos onde ela irá aparecer, devemos definir o ID do elemento da interface. Neste exemplo iremos exibir um ícone na barra de status. Adicione o código abaixo em "browser.xul".
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://exchangenotifier/content/style.css" type="text/css"?>
<!DOCTYPE overlay>
<overlay id="exn-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- Aqui vai o código XUL de nossa extensão -->
</overlay>
Essa é, provavelmente, a estrutura mais básica de um arquivo XUL que irá funcionar como "overlay". Temos um arquivo CSS que irá definir a formatação. O elemento overlay tem um ID único definido aqui como exn-overlay.
Você pode abrir este arquivo no Firefox para ver se ele está funcionando. Se tiver algo errado, uma mensagem de erro XML será exibida.
Um problema muito constante ao desenvolver extensões e agravado quando se está começando, é não saber quais são as tags disponíveis. O melhor lugar para se obter estas informações é em XULPlanet. Lá, você tem toda a relação de tags com uma descrição e exemplo de cada uma.
Por acaso, o elemento que precisamos adicionar chama-se statusbar. O elemento statusbar pode ter diversos elementos statusbarpanel, que nada mais são do que aqueles vários "quadradinhos" onde muitas extensões são exibidas.

Sabendo disso, já podemos adicionar nossa extensão à barra de status com o seguinte código:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://exchangenotifier/content/style.css" type="text/css"?>
<!DOCTYPE overlay>
<overlay id="exchangenotifier-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<statusbar id="status-bar">
<statusbarpanel id="exn-statusbar">
<image id="exn-icon" />
<label id="exn-label">–</label>
</statusbarpanel>
</statusbar>
</overlay>
Note como é simples a maneira que adicionamos itens ao browser. Todas as tags possuem nomes que remetem ao próprio elemento (statusbar, image, label, button, dialog).
Crie o arquivo "style.css" dentro do diretório "content". É ele que irá cuidar de toda a parte visual de nossa extensão. Adicione o seguinte conteúdo:
#exn-icon {
list-style-image: url("chrome://exchangenotifier/content/chart_curve.png");
}
A imagem utilizada nesta extensão foi retirada do pacote Silk Icons, disponibilizado por famfamfam.
Visualizando sua extensão
A maneira mais simples de visualizar a extensão durante o desenvolvimento, é movendo o diretório raíz para a pasta de extensões presente no seu perfil. Para quem usa Ubuntu Dapper o caminho padrão é ~/.mozilla/firefox/xxxxxxxx.default. No Windows XP (versão em inglês), o caminho é C:\Documents And Settings\USER\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default. Outros sistemas, não tenho a menor idéia. Faça um busca pelo diretório Profiles e você provavelmente encontrará. Leia mais aqui. Depois, basta reiniciar o Firefox para ativar a extensão.

Acesse o about:config e digite "exchangenotifier". Você verá que as preferências que colocamos no arquivo "prefs.js" foram adicionadas.

É isso aí! Espero que você tenha gostado da primeira parte deste artigo. Se tiver dúvidas ou sugestões, deixe seu comentário! Pegue a extensão que fizemos até agora, baixando o arquivo exchangenotifier-1.xpi.
Referências
- http://kb.mozillazine.org/Install.rdf#Creating_install.rdf_using_tools
- http://kb.mozillazine.org/Setting_up_extension_development_environment
- http://developer.mozilla.org/en/docs/Building_an_Extension
- http://developer.mozilla.org/en/docs/Install_Manifests
- http://www.rietta.com/~frank/firefox/Tutorial/overview.html
- http://roachfiend.com/archives/2004/12/08/how-to-create-firefox-extensions/
- http://www.hevanet.com/acorbin/xul/top.xul
- http://roachfiend.com/archives/2005/03/09/enabling-extension-updates/
- Posts relacionados
- ajax.js
Textos escritos por
Comentários #
Cara, muito interessante esse post. Eu não uso o Firefox aqui em casa, nem o IE, por increça que parível tenho usado um browser diferente, o K-meleon, acho que eu e uma meia dúzia de pessoas no mundo usam =/. Eu comecei a ler esse post agora, então ainda vou precisar aprender direitinho sobre o assunto antes de eu me aventurar em criar algum tipo de extensão, mas eu queria saber se é possivel usar extensões do firefox no k-Meleon. Caso eu queria usar a extensão "exchangenotifier", vc saberia me dizer o que tenho de fazer para habilitá-la no K-meleon? Caso isso seja possível de ser feito sem algum tipo de alteração no arquivo é claro.
Abraços
Olá Edu. Não sei te dizer como é o suporte à extensões do K-meleon. Se ele seguiu a mesma estrutura do Mozilla Suite, é possível, mas você terá que criar o arquivo "install.js", além de colocar o ID do browser. Seria interessante você entrar em contato com os desenvolvedores e perguntar em que nível está esse suporte. Se tiver alguma informação, posta aqui para vermos o que dá para fazer.
Olá Nando Vieira. Gostaria de saber se você pretende fazer a segunda parte deste artigo, gostei muito desta primeira parte, muito bem explicado, e gostaria muito de saber como termina.
Abraços
Olá Marcello! Já estou escrevendo a segunda parte. Como é um conteúdo um pouco extenso e tenho que alternar entre todas as outras coisas, estou enrolando... :P
Abraço!
Ok. Nando vou ficar esperando ansiosamente...afinal material de boa qualidade vale a pena esperar...
[...] Neste tempo fora, eu também montei um projeto mais humilde. É o 0BR. Ele serve como um encurtador de URL só que na linha Web 2.0. Está em beta mesmo, então ainda tem muita coisa para fazer. O Marco foi super solícito em ajudar, mesmo com o pouco tempo. O 0BR já conta com uma Extensão Firefox. Feita do zero, foi um exercício bem prazeroso de como construir uma extensão. O que me incentivou foi um post do Simples Idéias. Com a idéia geral na cabeça, parti para o tutorial do próprio Mozilla. A extensão é open source, se quiser brincar ou contribuir, manda ver. Tem também material aprendido/coletado de vários outros blogs, mas que acabei não anotando, mas se eu lembrar atualizo o post. O 0BR terá uma série de serviços assim que surgir mais tempo. [...]
É verdade, seria interessante fazer para o K-Meleon. Edu já descobriu algo a respeito?
A propósito, o número de usuários de K-Meleon vem crescendo muito, vemos isso claramente na comunidade do Orkut, inicialmente com poucos membros e hoje com 106 membros. Ele é feito sim com engine do Mozilla, e normalmente os plugins do Netscape que são compativeis. Quem puder ajudar poste aqui e/ou lá na comunidade também.
Olá, Nando!
Excelente o seu artigo. Muito esclarecedor, ainda mais pela falta de conteúdo de qualidade sobre o assunto disponível na Internet. Meus parabéns!
Agora, tenho uma dúvida: é possível fazer com que o Firefox abra um aplicativo local a partir de algum botão? Por exemplo, quero que haja um botão no browser para que ele execute o Kate (KDE users, uni-vos! hehe) ou o MSN (no caso do Windows).
Estive pesquisando sobre isso e não encontrei a solução...
Se souber de algo, por favor, me avise. ;)
Muito obrigado e, mais uma vez, parabéns.
Abraço.
Rafael, dê uma olhada no código fonte do FoxyTunes[1], pois é exatamente isso que ele faz.
[1] https://addons.mozilla.org/en-US/firefox/addon/219
Olá ! MUito bom mesmo o artigo, mas não consegui visualizar a extensão no about:config....o q pode ser???
AH, eu também espero anciosa a publicação da segunda parte ! Se puder me enviar um e-mail qdo estiver pronto ficarei muito feliz !
Muito legal o artigo. Parabéns! Se puder, me avise por e-mail quando for colocar a segunda parte do artigo.
A partir do seu artigo criei minha extensão. Consegui fazer até o velho "Hello, world". Mas agora "impaquei". E ai vai minha dúvida. Como faço para acessar Objetos da página através de minha extensão? O código abaixo parece não funcionar.
var linhas = window.document.getElementsByTagName('tr');
Desde já agradecido.
Olá Nando, como disse no comentário anterior, estou tentando fazer um pequena extensão a partir do seu artigo. Mas quando tento acessar qualquer elemento da página não vem nada. Um simples "window.document.getElementsByTagName('tr')" que deveria trazer uma coleção de linhas, simplesmente não traz nada. Será que tem a ver com segurança? Se poder dar um força, agradeço, pois achei muito interessante o artigo mas não consigo passar desse ponto.
Agradecido Sândalo Bessa.
Oi Nando, muito bom seu artigo. Estou tentando desabilitar o menu de contexto da barra de abas e o duplo click também, mas não tem jeito. Se você souber como bloquear também o shift+click-esquerdo para não abrir uma nova janela fico muito grato.
Obrigado Nando.
muito interessante sua matéria. consegui fazer minha "extensão" seguindo
o tutorial disponivel no developer.mozilla.org, mas sua matéria tirou muitas dúvidas.
agora quero implementar um jeito dela chamar funções em dll usando XPCOM mas esta dificil, hehe
se alguem estiver disposto a implementar algo juntos, contate-me
Muito bom o seu artigo gostaria de saber como faço para pegar o código html da pagina que esta ativa no firefox
olá Nando!
como fazemos para tirar uma extensão do firefox? grata.
No seu Firefox, clique em:
Ferramentas > Complementos
Na janela de complementos, selecione a aba "Extensões". As extensões instaladas no navegador estarão listadas lá. Basta clicar no botão "Desinstalar" da Extensão que você deseja.
[...] http://simplesideias.com.br/criando-extensoes-para-o-firefox-i/ [...]
Quando você fará a continuação?
[...] 22 days ago3 votesBackup das extensões do seu Firefox>> saved by colorhand 30 days ago1 votesSimples Idéias " Criando extensões para o Firefox - Parte I>> saved by nicknasty 32 days ago1 votes50 ótimas extensões para FireFox.>> saved by YUFKGJH 38 [...]
Uma pena não ter tido a continuação... eu fiz tudo direitinho, inclusive atualizei para versão 3 do FF. Mas não apareceu nada além do ícone gráfico e uma interrogação na frente...
Ola, gostaria de saber se vai sair a segunda parte do tutorial, e parabenizar pelo conteudo dessa primeira parte. Muito bom mesmo.
Ola você poderia fazer uma video aula e explicar melhor aonde coloca os comandos de linha para criar as extensões vlw ae, add seu site nos meu Fav
O tutorial é ótimo. Parabéns!
Se puder me envie o plugin pronto.
Tenho um plugin pra fazer, consigo logar por xmlhttprequest, mas não mantenho a sessão para solicitar as informações a serem exibidas no plugin.
Valeu!
tem como chamar uma função de uma dll, vi também que tem um arquivo com extensão .xpt
como criar?
Olá, amigo, muito bom. Não tinha a menor noção de como fazer. Você me deu uma idéia, porém, minha extensão inicial não é visualizada no about:config nem aparece, mesmo tenho salvo no perfil do firefox e reiniciado. O que pode ser?
Deixe um comentário