Esse é o último post da série de três posts que havia prometido sobre o tema "Consertando a web" ou, se preferir, "visualizando os sites do jeito que você quer". Não deixe de ler os dois primeiros: 1. Firebug e 2. Firebug + Stylish.
Como diz o título, hoje veremos como usar o Greasemonkey. Seguindo a linha learning by examples, mostrarei um caso de uso no webmail da Poli (se não me engano eles usam o Microsoft Outlook Web Access v.muito.antiga.pra.caramba).
Sobre
O Greasemonkey está para Javascript assim como o Stylish está para o CSS: essa é a melhor definição que posso dar pra quem já leu os posts anteriores. É possível definir um determinado script pra ser executado toda vez que você visita um determinado site. Com isso você ganha todo o poder que o Javascript pode te dar: além de poder mudar a aparência do site (como já era possível usando o Stylish), você pode acrescentar funções a serem chamadas em resposta a uma ação sua, acrescentar botões, elementos, tratamento de dados etc.
Motivação
Não tenho muito o costume de abrir o webmail da Poli, já que eu configuro o meu Gmail como cliente pop3 dele (assim posso ler meus emails da Poli junto com os do Gmail). O problema é o seguinte: o espaço de armazenamento disponível é de apenas (pasmen) 15 MB e eu não quero configurar o Gmail para apagar o email assim que o receber. Ou seja: a cada 2 meses recebo um email que minha caixa de emails está cheia e tenho que ir lá apagá-los.
Voltaremos a esse assunto na hora apropriada. Por ora, Greasemonkey!
Mão na massa
Você pode fazer o download dele no site de addons. Ou, se você está usando o Firefox 3.x simplesmente vá em Ferramentas > Addons, procure pelo addon Greasemonkey e pressione instalar - no melhor estilo linux de instalar de um repositório ;-). Depois de reiniciar o firefox, você já vai poder ver no canto inferior direito o símbolo dele.
Assim como com o Stylish, existe um site com vários scripts prontos para o Greasemonkey: userscripts. Recomendo dar uma olhada lá antes de sair escrevendo algum JavaScript.
Não é a intenção desse post explicar como programar em Javascript. Deixo isso para os diversos tutoriais que existem na web. Eu nunca programei em Javascript e fui mais pela intuição para fazer o que precisava; creio que para coisas simples, como algumas mudanças em algumas páginas web, não seja necessário um grande conhecimento nessa linguagem, além de que o "google é sempre seu amigo". Outra grande fonte de informação são os scripts presentes no site indicado acima; pegue um deles, dê uma olhada na implementação e faça o seu baseado em um deles.
O cabeçalho básico de qualquer Javascript a ser usado pelo Greasemonkey é o seguinte:
// ==UserScript==
// @name NomeDoSeuScript
// @namespace Site_de_referência
// @description Breve_descrição_do_que_ele_faz
// @include Site_para_o_qual_será_adicionado_o_seu_script
// @include Outro_site_para_o_qual_será_adicionado_o_seu_script
// ==/UserScript==
Você pode começar com esse cabeçalho no seu editor de texto favorito ou simplemente clicar com o botão direito no ícone do Greasemonkey, e selecionar a opção "New user script". Você verá a tela abaixo contendo os mesmos campos do exemplo acima. Basta preenchê-los e clicar em ok. Em seguida ele vai abrir o editor de textos para que você edite o script.
Como você pode ver na imagem acima, estamos começando o nosso script pra melhorar o webmail da poli. Veja que no campo include acrescentei o endereço do webmail da poli e também file:///*. Quando estamos testando os scripts, acho mais fácil salvar um html localmente com os elementos que queremos modificar/acrescentar do que ficar dando refresh no webmail. Com essa última opção, o Greasemonkey vai acrescentar seu script em qualquer página carregada do seu HD.
Uma coisa meio estúpida no webmail da Poli é que não tem como você selecionar todas as mensagens. Como disse acima, de tempos em tempos tenho que entrar lá com o simples motivo de apagar todas as mensagens e não tenho paciência de ficar selecionando mensagem por mensagem. Poderia resolver isso com um cliente pop3 em python bem fácil de fazer (que será assunto de um próximo post), mas quando o tal email dizendo "sua caixa de emails está cheia" chegou, era um sábado de manhã e eu estava afim de me divertir um pouco com o Greasemonkey.
A idéia é substituir aquela imagem de checkbox (que não tem utilidade nenhuma) por uma checkbox de verdade. Assim, quando o usuário clicar na checkbox a seleção das mensagens será invertida: foi uma maneira simples e prática que encontrei de poder deletar todas as mensagens ao passo que posso salvar algumas que achar importantes. Abaixo a imagem com a pseudo-checkbox.
Vamos fazer isso em duas partes. A primeira é: com a ajuda do Firebug descobrir o nome do arquivo daquela imagem e usando Javascript substituir por uma checkbox. A segunda parte é fazer com que ao clicar na checkbox a seleção das mensagens seja invertida. A imagem abaixo mostra o uso do Firebug:

Substituindo a pseudo-checkbox por uma checkbox de verdade
O código abaixo implementa a primeira parte.
var img = document.evaluate('//img[@src=\'/exchweb/img/view-mark.gif\']', document, null,
XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
GM_log('Numero de elementos = ' + (img==null?'0':'1'));
if(img){
var chk = document.createElement('input');
chk.type='checkbox';
img.parentNode.replaceChild(chk,img);
}
Algumas coisas importantes de se notar:
- GM_log é a função para logar o que você quiser. É muito útil pra debug de Javascript. Você pode ter acesso a essas saídas em "Ferramentas > Console de Erro" no Firefox;
- A chamada document.evaluate é que faz o trabalho pesado de encontrar a imagem que estamos procurando. Ela recebe como primeiro parâmetro uma query XPath. No exemplo acima estamos procurando todos os elementos img do HTML com um parâmetro src='/exchweb/img/view-mark.gif';
- O if(img) está ali porque como o webmail usa frames, está sendo carregada mais de uma página "em baixo" de https://www.poli.usp.br/mail/. Ou seja, tem a página correspondente ao frame da esquerda e outra correspondente ao da direita. Como no da esquerda não tem nenhuma imagem com esse argumento, img será null nesse caso. Foi por isso que eu coloquei aquela mensagem no log: você pode verificar que ele loga dois valores "Numero de elementos = ..." quando você carrega o webmail;
- A última linha pega o nó pai da figura e faz com que ela seja substituída pela checkbox que criamos.
Executando uma função toda vez que a checkbox é clicada
A segunda parte consiste em aganchar um listener do evento click na recém-criada checkbox e criar uma função para inverter a seleção atual. Novamente usando o Firebug, descobrimos que as checkboxes que (de)selecionam as mensagens têm Name='MsgID'. Logo, a função de inversão de seleção deve somente acessar essas checkboxes invertendo o valor atual da propriedade "checked". Segue abaixo a função:
A função para inverter a seleção
function invertSelection(e){
var checkboxes;
checkboxes = document.getElementsByName('MsgID');
for (var i=0; i< checkboxes.length; i++)
checkboxes[i].checked= !checkboxes[i].checked;
GM_log('User click');
e.stopPropagation();
}
Para aganchar o listener para que essa função seja chamada toda vez que a nossa "checkbox-invert-selection" for clicada, basta fazer como segue, antes de trocar a imagem pela checkbox:
chk.addEventListener('click',invertSelection,false)
Conclusão
O código completo você pode encontrar aqui (licenciado sob a GPL): betterpoliwebmail.user.js. Abaixo algumas fotos desse script em ação.
==> 
==> 
Para terminar deixo a dica do manual do greasemonkey: dive into greasemonkey.
Com esse post encerro a série de 3 posts prometida sobre esse assunto. Espero que tenham gostado. Abaixo uma frase de Linus Torvalds em uma palestra sobre o git para pensar: "Intelligence is the ability to avoid doing work, yet getting the work done".