Criando extensões para o Firefox - Parte I
Leia em 8 minutos
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@nandovieira.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@nandovieira.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://nandovieira.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/