Arquivo da tag: javascript

Como copiar textos da Folha e outros sites que não deixam

Alguns sites começaram a abusar de um recurso super interessante do JavaScript para acabar com uma das características mais importantes da Internet: a capacidade de copiar/colar.

O tratamento dos clipboard events (oncut, oncopy e onpaste) deveria servir para permitir que os programadores façam coisas legais quando você copia/cola um texto (por exemplo, um processador de textos online pode inserir/remover formatação), mas tenho visto cada vez mais ele ser usado para adicionar uma mensagem de copyright no final de um texto copiado, impedir usuários leigos de copiarem textos na web e evitar que se cole coisas que você copiou em formulários.

O que mais me incomoda (e que me levou a escrever esta postagem) é que, hoje, quem copia um trecho de uma reportagem da Folha (para guardar, compartilhar numa rede social ou o que quer que seja) acaba colando:

Para compartilhar esse conteúdo, por favor utilize o link http://www1.folha.uol.com.br/fsp/bla-bla-bla ou as ferramentas oferecidas na página. Textos, fotos, artes e vídeos da Folha estão protegidos pela legislação brasileira sobre direito autoral. Não reproduza o conteúdo do jornal em qualquer meio de comunicação, eletrônico ou impresso, sem autorização da Folhapress (pesquisa@folhapress.com.br). As regras têm como objetivo proteger o investimento que a Folha faz na qualidade de seu jornalismo. Se precisa copiar trecho de texto da Folha para uso privado, por favor logue-se como assinante ou cadastrado.

Não é incrível (e sintomático) que o grupo que gerencia o portal mais importante da Internet no Brasil (UOL) tenha uma concepção tão atrasada da rede? Ok, não dá nem pra dizer que isso nos surpreende depois da censura da Falha e do paywall.

Sem mais delongas: isso merece ser hackeado. Neste post, proponho algumas soluções simples para você poder voltar a copiar e colar no seu navegador como sempre fez. Minha preferida, como sempre, é a última.

Solução trivial para quem usa Linux

Antes de sugerir soluções de verdade, convém observar que quem usa Linux (X11) pode copiar selecionando um texto (sem apertar Ctrl+C ou qualquer outra combinação esdrúxula de teclas) e colar apertando o botão do meio do mouse. Quando se copia/cola dessa forma, o navegador não emite os temidos eventos oncopy/onpaste (ou seja, tudo funciona normalmente).

Rodolfo Mohr também observou que você pode copiar um texto selecionando-o, clicando com a tecla direita na seleção e em “Pesquisar no Google”. Uma aba vai abrir com a pesquisa no Google e você pode copiar o texto lá. É um hack válido, embora incômodo.

Somente Firefox: usando about:config

Se você usa Firefox, pode desabilitar os clipboard events digitando, na barra de endereços, em about:config. Talvez ele diga que é perigoso e peça para você clicar num botão dizendo que sabe o que está fazendo. Pode confiar. Em seguida, procure a chave dom.event.clipboardevents.enabled e clique duas vezes nela para mudar seu valor para false. Reiniciando o navegador, o recurso copiar/colar estará funcionando normalmente (ou talvez nem precise reiniciá-lo).

Extensões (para Firefox, Chrome e Opera)

Não tem o que explicar. Simplesmente clique no nome do seu navegador e instale: Firefox, Chrome, Opera.

Editado em 01/04/2014, 22:30: A extensão que eu havia colocado para Chrome só desabilita o tratamento de eventos onpaste em formulários. Se você conhecer alguma extensão similar a do Firefox ou a do Opera, me avise pelos comentários.

Desabilitando sob demanda via JavaScript

É muito importante ter em mente que aplicações web como processadores de texto podem usar os eventos oncut/oncopy/onpaste para coisas úteis. Por isso, é desejável desabilitar esses eventos somente em sites específicos.

Não encontrei nenhuma extensão que faça isso, mas um código simples em JavaScript para recuperar o comportamento padrão dos eventos em um determinado site (testei no Firefox e no Chrome) é:

all = document.querySelectorAll("*");
fn = function(e) {
    e.stopPropagation();
    return true;
}
for (var i = 0; i < all.length; i++) {
    all[i].oncut = fn;
    all[i].oncopy = fn;
    all[i].onpaste = fn;
}

Se digitarmos isso no console (Shift+Ctrl+J), as funções copiar/colar devem voltar a funcionar.

Userscript

A solução anterior nos permite criar um userscript para desabilitar o tratamento dos eventos apenas no site da Folha:

// ==UserScript==
// @name Permite copiar textos da Folha
// @include http://*.folha.uol.com.br/*
// ==/UserScript==
 
window.onload = function() {
    all = document.querySelectorAll("*");
    fn = function(e) {
        e.stopPropagation();
        return true;
    }
    for (var i = 0; i < all.length; i++) {
        all[i].oncut = fn;
        all[i].oncopy = fn;
        all[i].onpaste = fn;
    }
}

Portanto, se você quiser copiar do site da Folha sem preocupações (e sem desabilitar os eventos em outros sites), pode instalar as extensões GreaseMonkey (Firefox) ou TamperMonkey (Chrome), e então esse userscript clicando neste link: falha.user.js.

Bookmarlet

Acho o método acima (do userscript) o melhor para copiar da Folha. No entanto, é conveniente ter um método mais genérico. Por isso, criei um bookmarklet, isso é, um pequeno script que podemos executar clicando num botão na barra de favoritos (neste caso, para restaurar o comportamento padrão das funções copiar/colar).

Aqui está ele: Restaurar copiar/colar

Para instalar, arraste esse link para sua barra de favoritos. Para usar, clique sempre que precisar copiar um texto e então copie normalmente.

Viva a Internet!

Como ler documentos do Scribd

Depois de ouvir esse improviso do André Mehmari sobre Odeon e Choro pro Zé, fiquei com vontade de encontrar a partitura desse belo choro do Guinga. Porém, descobri que infelizmente é extremamente difícil encontrar o songbook “A música de Guinga”.

Procurando na rede, encontrei um torrent com um PDF com qualidade ruim e um documento do Scribd com qualidade boa. O problema é que o Scribd tem um paywall para não deixar as pessoas baixarem ou lerem os documentos que seus usuários colocam lá:

free-preview

Percebi que ele passa todas as imagens corretamente para o navegador e só no lado do cliente muda a opacidade das páginas para elas ficarem semitransparentes. Então escrevi um userscript bem simples (usando jQuery por comodidade) para o Greasemonkey (uma dessas extensões indispensáveis do Firefox) para recuperar a opacidade das páginas do texto e, se necessário, remover essa mensagem “You’re reading a free preview”.

// ==UserScript==
// @name Suppress Scribd Paywall
// @include http://*.scribd.com/doc/*
// @require http://code.jquery.com/jquery-2.0.3.min.js
// ==/UserScript==
 
(function($) {
    $(document).ready(function() {
        window.setInterval(function(){$(".absimg").css("opacity", "1")}, 1000);
        $(".autogen_class_views_read_show_page_blur_promo").on("click", function(e) { $(this).hide(); });
    });
})(jQuery);

Para usar, é só instalar o Greasemonkey no Firefox e depois baixar o userscript scribd.user.js. Resultado:

choro-pro-ze

Como ler notícias ilimitadas de Folha, Estadão e Globo sem cadastro

TL;DR: Instale o Adblock Plus em seu navegador, entre nas suas opções, peça para adicionar seu próprio filtro e adicione o filtro: *paywall*. Você agora deve ser capaz de ler notícias de Folha, Estadão e Globo sem cadastro. Caso tenha interesse em saber o caminho que levou a solução até aqui, continue lendo o post.




A mídia tradicional mudou a forma como publica na internet. A regra agora é que sem cadastro você só pode acessar um determinado número (pequeno) de notícias. O nome do sistema é paywall. Ao chegar no limite, você recebe mensagens como as seguintes:

folha estadao globo
Folha, Estadão e Globo quando você lê muitas reportagens

No caso da Folha, só o cadastro pago dá acesso ilimitado. Nos outros, aparentemente um cadastro gratuito é suficiente. De qualquer forma, por que dar seus dados para esses sites saberem quem você é, como navega e o que gosta de ler? Para quem esses sites vão dar essas informações?

Para além da preocupação com privacidade e anonimato, esse sistema funciona como um bloqueio para que as pessoas não possam ler e disseminar as notícias da internet. Torna a circulação de informações mais difícil e o espaço internético mais privado e menos democrático. Por isso, compartilho aqui um pouco sobre o funcionamento do paywall e algumas formas de contorná-lo.


Os sites não querem que buscadores tenham dificuldade de acessar e indexar seu conteúdo. Tampouco querem bloquear endereços de IP, já que a quantidade de pessoas que usa internet via NAT (compartilhando o mesmo endereço de IP com outras pessoas numa mesma rede) é enorme. Por isso, eles fazem todo o controle não no computador deles (servidor), mas no seu computador (cliente).

Para fazer isso, eles contam com a ajuda do seu navegador. Eles mandam a página sempre da mesma forma e o seu navegador é que faz o trabalho sujo. Roda um programa escrito em JavaScript para olhar pros dados que ele mesmo já tinha registrado anteriormente (os chamados cookies). Baseado nesses dados, redireciona você para outra página (no caso de Folha e Estadão, simplesmente coloca um fundo preto semi-transparente em cima do conteúdo do site).

Isso torna não só possível, como trivial contornar o bloqueio. Basta dizer para o seu navegador não registrar cookies, desativar a execução de JavaScript ou rodar outro programa para anular a ação do programa da grande mídia. Abaixo vou mostrar diversas formas de fazer isso usando o Mozilla Firefox, mas em outros navegadores há formas semelhantes de fazer o mesmo. Como sempre, a última forma é a que eu considero melhor.

Usar janela de navegação privada

A forma mais simples de acessar um conteúdo bloqueado é acessar a página numa janela de navegação privada. Para abrir tal janela, basta usar o atalho Ctrl+Shift+P no Firefox (ou Ctrl+Shift+N no Chromium). Como essa janela não vai usar os cookies que seu navegador tem registrado na janela principal, você vai conseguir acessar o conteúdo proibido normalmente (como se nunca tivesse acessado nenhuma notícia antes). Há pessoas que usam só o modo de navegação privada o tempo todo (uma opção razoável para evitar rastreamento).

Remover cookies individuais

No Firefox, você pode usar Editar → Preferências → Privacidade → Remover cookies individuais para remover cookies registrados no seu computador. Se você remover todos, vai sair automaticamente de todos os sites onde está logado. Como seu objetivo é contornar o paywall, você pode remover cookies somente dos sites que deseja acessar (no caso, procurar globo, folha e estadao na barra de busca da remoção de cookies).

Desativar JavaScript

É possível desativar a execução de programas enviados pelos sites que você acessa no Firefox desmarcando a caixa Permitir JavaScript no menu Editar → Preferências → Conteúdo do Firefox. Dessa forma, você vai perder muitas funcionalidades dos sites, mas navegar mais rápido e não ter que encarar paywall algum.

A extensão NoScript do Firefox torna mais fácil ativar/desativar scripts de determinados domínios.

Desativar CSS

Se você não se importar com leiaute e diagramação da página, Exibir → Estilos da página → Nenhum estilo vai fazer tudo ficar feio, mas o texto legível.

Usar extensão Web Developer

Instalar a extensão Web Developer no Firefox torna ainda mais simples remover cookies de um determinado domínio e desativar JavaScript ou CSS (aparece uma barra embaixo da barra de endereço com botões pra executar essas ações).

Remover lightbox

No caso de Folha e Estadão (que sobrepõe um fundo preto semi-transparente e uma lightbox na página ao invés de redirecionar você para outra página como faz o Globo), é possível fazer a lightbox desaparecer (sem mexer nos cookies ou no JavaScript) usando o modo de inspeção (Ctrl+Shift+I), selecionando os elementos que quer remover e adicionando o CSS display:none; neles. Por meio de um userscript do Greasemonkey seria possível automatizar isso.

Forma definitiva (minha preferida): filtros no Adblock Plus

Adblock Plus é uma extensão do Firefox extremamente eficiente para bloquear publicidades e scripts não desejados. Os seguintes filtros bloqueiam os scripts de paywall de Folha, Estadão e O Globo:

||paywall.estadao.com.br^
||estadao.com.br/paywall/*
||www1.folha.uol.com.br/folha/furniture/paywall/*
||static.folha.com.br/paywall/*
||oglobo.globo.com/servicos/inc/payWall.Conteudo.js
||oglobo.globo.com/plataforma/js/*/minificados/paywall/registraConteudosLidos.js

(Depois de escrever, fiquei pensando que talvez seja razoável bloquear simplesmente *paywall* de uma vez.)

Para usar, basta ter instalado o Adblock Plus, copiar essas regras (todas juntas) e colá-las em Ferramentas → Adblock Plus → Preferências de filtros → Filtros personalizados.

Como baixar fotos dos álbuns da UOL

ATENÇÃO: Este conteúdo foi publicado há 5 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Se você não é nerd, não tem tempo, não tem coração e não tem curiosidade, recomendo que ignore todo o texto e leia somente o item 3.

Por causa da forma como os álbuns de fotos do UOL são feitas, copiar suas fotos é uma tarefa difícil para a maioria dos usuários. Não acho que a UOL faça assim de propósito, mas por uma questão de usabilidade mesmo: há dois botões enormes em cima das fotos para você avançar para a próxima foto ou voltar para a anterior, e é por causa deles que você não consegue ver o “Copiar endereço da imagem” quando clica com a tecla direita na área da imagem (porque você não está realmente clicando na imagem, mas num botão transparente).

No entanto, há várias formas de copiar fotos dos álbuns da UOL. Neste post apresento algumas. Para testar, você pode tentar aplicar essas ideias neste álbum.

0. Soluções toscas

Como eu disse no início, os webmasters do UOL aparentemente não fazem os álbuns se comportarem assim de propósito, mas por causa de botões gigantes. A maneira mais fácil de copiar uma foto de um álbum do UOL é clicar bem na coluna exatamente no meio dela, evitando as duas setas. Você pode passar o mouse devagar pelo meio da foto até que o seu cursor deixe de ser uma mãozinha e seja uma seta. Pra saber se você deve ir pra esquerda ou pra direita é só ir na direção da seta que você não está vendo.

Outra solução também tosca é simplesmente tirar um screenshot da tela em que você está (apertar a tecla PrintScreen na maioria dos computadores deve funcionar) e recortar a imagem. Eu imagino que essa seja a solução mais usada, mas pessoalmente acho ela terrível.

Não pare de ler! Prometo que as próximas soluções vão ser mais legais.

1. Somente para o Firefox: desativar estilos

Desativar o CSS da página é uma forma fácil de acabar com todo seu leiaute e dessa forma copiar a imagem sem se preocupar com perfumarias. Você provavelmente pode fazer isso em qualquer navegador usando plugins (e nos navegadores que não suportam CSS é até mais fácil: você nem precisa fazer nada!) e no Firefox em particular há um botão no menu (Exibir » Estilos » Sem estilos).

2. JavaScript na barra de endereço

Em geral, você pode escrever um script na barra de endereço para executá-lo na página em que você está. Há um tempo atrás todos os navegadores aceitavam isso, mas aparentemente muitos têm desativado esse recurso por questões de segurança, inclusive o Firefox. De qualquer maneira, se seu navegador suportar, você pode simplesmente digitar:

javascript:document.getElementById("setaEsq").style.width=document.getElementById("setaDir").style.width="50px";void(0);

na barra de endereço quando estiver na página do álbum do qual quer baixar fotos.

Isso vai reduzir o tamanho dos botões, fazendo com que a área clicável seja bem maior.

Exercício para quem souber ou quiser aprender JavaScript: Escreva um script que abra a foto numa nova aba em vez de simplesmente deixá-la clicável. Transforme-o num bookmarlet (veja o próximo item).

3. Bookmarlet

A solução anterior nos incentiva a criar um botão que execute esse script para não termos que decorá-lo nem copiá-lo sempre. Eis aqui esse botão para você: Aumentar área clicável das fotos dos álbuns da UOL. Clique com a tecla direita nesse link e adicione-o aos seus favoritos. Quando você estiver num álbum, clique nesse favorito e a imagem vai se tornar magicamente clicável :)

4. Firefox e GreaseMonkey

Se você usa Firefox e tem instalada a extensão GreaseMonkey, instale o seguinte user script (que executa o mesmo código que colei no item 2) e sempre que você abrir um álbum as fotos serão clicáveis: Download do userscript

// ==UserScript==
// @name Copiador de fotos UOL
// @description Torna mais fácil copiar fotos de álbuns da UOL
// @author  Tiago Madeira <contato@tiagomadeira.com>
// @include http*://*.uol.com.br/album/*
// @version 0.9
// ==/UserScript==
 
(function(){
    window.onload = (function() {
        document.getElementById("setaEsq").style.width = "50px";
        document.getElementById("setaDir").style.width = "50px";
    });
})();

Mas estou lendo este post em 2020 e o UOL mudou! Ou eu quero baixar fotos do site X, não do UOL!

A solução 1 (desativar estilos) funciona em 99% dos casos. Não quer ver sites sem estilo? Continue lendo.

5. Se você não quiser utilizá-la e se você estiver usando Firefox, pode clicar no ícone ao lado do endereço do site na barra de endereço e aí no botão “Mais informações”. Isso vai abrir uma tela com uma seção “Mídia” onde é possível ver e salvar imagens, ícones e vídeos que seu navegador baixou para mostrar a página. Esse método funciona também para copiar vídeos HTML5, inclusive do YouTube:

6. Se você não quiser procurar uma imagem no meio de um monte de mídias, a última versão do seu navegador deve ter um botão “Inspecionar elemento” no menu de contexto sempre que você clica com a tecla direita em qualquer lugar da página. Usando essa ferramenta é possível ver o código HTML do que você está vendo (ela é diferente e melhor do que simplesmente ver o código-fonte da página porque usando a inspeção de elementos você vê o código do momento atual, depois dos scripts mudarem as coisas). Se você pedir para inspecionar alguma coisa transparente em cima da imagem, em geral não vai ser difícil achar a própria imagem. Este screenshot é do Chrome:

Há inúmeras soluções mais nerds, mas quis manter a lista com sugestões fáceis e que não precisam de nada além do seu navegador. Alguma outra ideia simples, criativa e divertida? Blogue por aí ou me conte pra eu aumentar a lista!

Retrospective: new plugin for WordPress

ATENÇÃO: Este conteúdo foi publicado há 6 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

I’ve just wrote my first WordPress public plugin, that I’m licensing under GPL v3. This post is to make it public. I’m writing in English because the WordPress plugin directory asks me to provide a plugin page to host the files there and I’ll provide the URL of this post. Update: The plugin is now in the WordPress plugin directory: wordpress.org/extend/plugins/retrospective/


The website of the brazilian newspaper O Estado de São Paulo has a nice way to display news in a retrospective-style (check this screenshot or this link — Flash required).

Wouldn’t it be nice if we could display WordPress posts in our pages and categories in the same way just by using a shortcode? The possibilities are many. That’s why I wrote the Retrospective plugin for WordPress.

It has at least two advantages over the version you just saw:

  1. Does not require Flash (its implementation uses only CSS and JavaScript/jQuery)
  2. Has a option to respect the (time-)scale of the posts.

Its use is very simple. Wherever you add the shortcode [retrospective] the plugin will draw that cool retrospective. The shortcode supports several attributes:

  • count — limit the number of posts to be displayed (default = 10; use -1 to display all)
  • cat — display posts with category IDs comma-separated (default = display all posts)
  • width — the width of the timeline in pixels (default = 600)
  • delay — the time of the focus change animation in milisseconds (default = 1000)
  • scale — if set, respect the time scale in the distances between the points in the timeline (default = false)
  • image_width, image_height — the dimensions of the thumbnail images in pixels (default = 300×180)
  • image_border_size — the size of the image’s border in pixels (default = 7)
  • image_border_color — the color of the image’s border in hexa RGB (default = 000000)
  • image_margin — the space between the images (default = 5)
  • date_format — the date format in PHP format (default = d/m/Y)

For example, here is a [retrospective count=5 cat=20 image_border_color=2F5971] call:


Some screenshots

Here is a screenshot from juntos.org.br with scale=true (in the link you can see it working):

And here is a screenshot from a fresh WordPress install (TwentyEleven theme without modifications):


Customizing

Post thumbnails

For better results, I suggest always adding post thumbnails to your posts and using registered image sizes in image_width and image_height attributes.

Styling retrospectives

The generated HTML is very easy to style (but just be careful with margins and paddings, they’re set with !important attribute — I did it to try not to break with any theme). Here is a sample:

<div id="retro-uniquehash" class="retrospective">
    <!-- TIMELINE -->
    <ul class="time">
        <li rel="0"><a href="permalink" style="left:0px;"><span>date</span></a></li>
        <li rel="1"><a href="permalink" style="left:300px;"><span>date</span></a></li>
        <li rel="2"><a href="permalink" style="left:600px;"><span>date</span></a></li>
    </ul>
 
    <!-- PHOTOS -->
    <div class="photos">
        <ul>
            <li rel="0"><a href="permalink" title="title">
                <img src="file" class="wp-post-image" /></a></li>
            <li rel="1"><a href="permalink" title="title">
                <img src="file" class="wp-post-image" /></a></li>
            <li rel="2"><a href="permalink" title="title">
                <img src="file" class="wp-post-image" /></a></li>
        </ul>
    </div>
 
    <!-- POSTS -->
    <ul class="posts">
        <li rel="0"><a href="permalink" title="title"><h2>Title <span>(date)</span></h2>
            <p>Excerpt</p></a></li>
        <li rel="1"><a href="permalink" title="title"><h2>Title <span>(date)</span></h2>
            <p>Excerpt</p></a></li>
        <li rel="2"><a href="permalink" title="title"><h2>Title <span>(date)</span></h2>
            <p>Excerpt</p></a></li>
    </ul>
</div>

Styling a specific retrospective

The generated hash takes in consideration all the attributes sent to the shortcode and also how many retrospectives appeared before in the parsing of the actual page. I made it that way to allow users to set up two exactly equal retrospectives in the same page. Because of that, I don’t recommend setting styles for #retro-uniquehash. I think a reasonable solution for this issue is to make something like

<div id="something_that_makes_sense">[retrospective]</div>

when inserting the shortcode and then styling #something_that_makes_sense .retrospective.


Download

Here is the code for download:* retrospective.zip
* Warning: Please consider I’m using a bazaar approach here. Be aware that the plugin probably has a lot of bugs (and please tell me if you catch any).

I hope you enjoy it. Have fun and please let me have your feedback! :)

Userscript para remover usuários de grupos do Facebook

ATENÇÃO: Este conteúdo foi publicado há 6 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Já faz algum tempo que o Facebook tem um bug nas listas de membros dos grupos. As listas não mostram todos os membros do grupo. Mais: os membros que não aparecem na lista nem mesmo podem ser encontrados pelo formulário de busca de nomes. Quando você é administrador de um grupo, isso pode ser um grande inconveniente, porque na interface padrão do Facebook a lista de membros é o único lugar onde é possível excluir usuários de um grupo. Ou seja, os usuários que não aparecem lá são indeletáveis!


Só ali na lista de membros aparece esse X para excluir os membros do grupo.

Há alguns meses, escrevi um user script para o GreaseMonkey (extensão para o Firefox que permite que você crie esses pequenos scripts para serem rodados em páginas específicas) que busca ajudar os administradores de grupos a removerem esses membros fantasmas.

Não havia publicado até agora por vergonha (o script é bem feio, tanto o código como o resultado). Porém, acho que não pretendo perfumá-lo tão cedo, então resolvi liberá-lo aqui até pra inspirar quem quiser fazer coisas mais bonitas.

O funcionamento dele é muito simples: quando você entra num grupo (sendo ou não administrador — porque nem distingui isso no código), ele cria botões X do lado dos links para os perfis dos usuários que estão nessa página (e só nesses — outra coisa que nem me preocupei no script). Se você for administrador do grupo em questão, quando clica no X o Facebook abre aquela caixa perguntando se você quer mesmo excluir o membro em questão (e se quer baní-lo permanentemente).


Com o script, tem X em todo o lugar! (até onde não deve… hehe)

Sem mais enrolação, eis aqui o código para (des-)apreciação e aprimoramentos (por favor! :)):

// ==UserScript==
// @name Remove users from Facebook groups
// @description Remove usuarios que postam no grupo sem precisar procurar na lista de membros
// @author  Tiago Madeira <madeira@juntos.org.br>
// @include http*://www.facebook.com/groups/*
// @version 1.32
// ==/UserScript==
 
(function(){
    var as = document.getElementsByTagName("a");
    var gid = "";
 
    for (var i = 0; i < as.length; i++) {
        var a = as[i];
        var hovercard = a.getAttribute("data-hovercard");
        if (hovercard != null && hovercard != "") {
            uid = hovercard.replace(/.*id=/, '');
            if (gid != "") {
                var button = '<a class="mhm auxiliaryButton closeButton uiCloseButton" title="Remove" rel="dialog-post" href="/ajax/groups/members/remove.php?group_id=' + gid + '&uid=' + uid + '"></a>';
                a.innerHTML = a.innerHTML + " " + button;
            }
        }
        var pattern = new RegExp("(^| )groupsCleanProfilePic( |$)");
        if (pattern.test(a.className)) {
            gid = a.getAttribute("href").replace(/.*id=/, '');
        }
    }
})();

Ou o link direto para download (ou instalação no GreaseMonkey):

fb.group.remove.user.js (1.08kb)

Novo design!

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Novo template feito em tempo recorde… Três dias foram necessários para eu finalizar o novo design do meu site, agora mais leve e acessível (e mais bonito).

Com a folha de estilos CSS mais organizada, menos ícones, mais simplicidade, texto mais legível (com detalhes pouco aproveitados em muitos sites como line-height e text-indent) e um logo que o Cosme fez pra mim por caridade; espero que curtam o novo design e, se quiserem, sugiram mudanças!

Agora eu também fiz um arquivo de JavaScript já preparado para futuras aplicações Ajax e pretendo ir adicionando detalhes legais aos poucos.

Comentem dando as suas opiniões!

LiveSearch no WordPress

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

O Cosme me apresentou hoje um projeto chamado LiveSearch. É uma aplicação Ajax bem simples (eu mesmo conseguiria fazer), mas uma idéia que eu ainda não havia tido.

Resolvi então implementar o negócio no meu blog e estou escrevendo esse artigo pra explicar como instalamos o LiveSearch de forma que ele funcione com o WordPress e dentro dos padrões de XHTML Strict (ele pede originalmente que utilizamos name num form e exige que o nome de um campo seja “q” ao invés do “s” do WordPress).

Então, mãos a obra!

1. livesearch.php

Para começar, você deve criar um arquivo e chamá-lo livesearch.php. O seu conteúdo deve ser:

<?php if (have_posts()) : ?>
<ul class="LSRes">
<?php while (have_posts()) : the_post(); ?>
	<li class="LSRow">
		<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>

Para facilitar para quem quer aprender PHP, vou explicar linha por linha:

  1. Se houver posts, faça:
  2. Lista HTML
  3. Enquanto houver posts: Execute a função the_post().
  4. Item da Lista HTML
  5. Linca para o permalink do post com o texto do link = seu título.
  6. Fim do “Item da Lista HTML”
  7. Fim do “Enquanto houver posts”
  8. Fim da “Lista HTML”
  9. Fim do “Se houver posts”

Observação: As cores são só para reforçar a hierarquia.

O que este arquivo faz, portanto, é criar uma lista com o título dos posts. Essas funções são todas do WordPress (have_posts, the_title, the_permalink, etc.). Se você quisesse colocar outras coisas na lista que vai aparecer no resultado, pode colocar aí nesse arquivo.

No fim, salve esse arquivo em /wp-content/themes/SEU_TEMA/livesearch.php.

2. Redirecionar para livesearch.php se for uma pesquisa “live”

Coloque no início do arquivo /wp-content/themes/SEU_TEMA/search.php o seguinte conteúdo:

<?php if ($_GET["live"]) {
		include("livesearch.php");
		die();
	} ?>
  1. Se a query string live “existir”, faça:
  2. Inclua o arqiuvo livesearch.php nessa página.
  3. Morra!!! :D Isso significa para ele parar de executar qualquer coisa que esteja debaixo disso.
  4. Fim do “Se”

Isso serve para que possamos fazer as buscas de duas maneiras. Uma é a busca normal, que é acessada por /?s=queries e outra é a live que será acessada por /?live=1&s=queries (ou seja, a mesma coisa mas dando valor à variável “live”).

3. JavaScripts

Baixe o arquivo livesearch.js e coloque-o na pasta /wp-content/themes/SEU_TEMA/.

Agora faremos uma série de mudanças pra manter o negócio nos padrões web… Substitua as seguintes linhas pelo texto que aparece depois do seu número:

  • 122: if (liveSearchLast != document.getElementBy(‘livesearch’).value) {
  • 126: if ( document.getElementById(‘livesearch’).value == “”) {
  • 136: liveSearchReq.open(“GET”, liveSearchRoot + “/?live=1&s=” + document.getElementById(‘livesearch’).value + liveSearchParams2);
  • 137: livesearchLast = document.getElementById(“livesearch”).value;

Isso serve para ele não depender do nome do formulário e da query, mas somente do ID do campo do formulário e para ele abrir no xmlHttpRequest /?live=1&s=QUERY ao invés do padrão /livesearch.php?q=QUERY.

4. Eventos JavaScript nos documentos

No seu arquivo /wp-content/themes/SEU_TEMA/header.php, adicione o evento onload à tag BODY:

<body onload="liveSearchInit()">

No mesmo arquivo, dentro da tag HEAD linke para o script:

<script type="text/javascript" src="/wp-content/themes/SEUTEMA/livesearch.js"></script>

Agora, no arquivo /wp-content/themes/SEU_TEMA/searchform.php, adicione um evento onsubmit ao FORM

<form onsubmit="return liveSearchSubmit()" ...

E, no mesmo arquivo, adicione um evento onKeyPress ao INPUT e também um id:

<input id="livesearch" onKeyPress="liveSearchStart();"

E ao final desse arquivo, coloque:

<div id="LSResult" style="display: none;">
<div id="LSShadow">
</div>
</div>

Se você fez tudo certo e eu não errei aqui no tutorial, o seu script deve sair funcionando! Agora personalize usando estilos pra fazer um negócio bonito! (algo que eu não fiz porque tô pra trocar totalmente o design do meu site)


A Lógica do Negócio

O arquivo search.php recebe todas as buscas. O que eu fiz criando o livesearch.php foi formatar o resultado da busca de forma diferente para ele aparecer ali debaixo do formulário de busca.

O script é bem simples. Um Ajax que simplesmente faz um xmlHttpRequest a cada keypress do cara no campo. Aliás, acho que dá pra fazer um script bem menor pra só fazer isso.

Deixei o meu site meio feio com isso aí (uma lista de bullets normais e tal…), mas é porque eu tô pra trocar o design em breve e aí vou arrumar isso tudo! (inclusive, devo colocar mais Ajax!)

Qualquer dúvida, comente ou me mande um e-mail.

Álbum de Fotos

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Link para projeto em desenvolvimento…

Meu Flickr tá estourando (depois de 200 fotos, começam a sumir fotos segundo seu FAQ) e por isso resolvi criar um álbum de fotos pessoal. Estou desenvolvendo em PHP, usando um banco de dados MySql e estou criando bastante recursos Ajax para exercitar um pouco e para o negócio ficar bem dinâmico (se estiver ficando muito exagerado, me avisem!). Este projeto que ainda não tem nome, mas que estou pensando em algo como PhotoX (gostou do nome? comente! não gostou? comente também!), deve ter todos os recursos do Flickr (tipo, All Sizes, Notes e Rotate) e o que surgir de idéias legais. Será um software livre, cada um instala em seu servidor (ex.: é um “WordPress“, não um “Blogger“) e por isso ele não tem limites de sets, tags, fotos, tamanhos ou qualquer coisa do tipo. Irá requerer PHP 4.3, está sendo desenvolvido usando classes (estou tentando exercitar programação orientada a objetos), usa a biblioteca GD (para trabalhar com as imagens) e é totalmente Web 2.0 (tableless, padrões HTML 4.01 Strict, Ajax, tagsonomia, simplicidade). Já estou o criando multi-linguagem, ele funciona com alguma coisa parecida com templates e deve sair em no máximo um mês.

Estou convidando programadores sem nada pra fazer pra me dar uma ajuda (claro que gratuita). O Gustavo é uma das pessoas que me deu uma ajuda fazendo um pedaço da classe Foto e da classe Comentario e aqui estendo o convite para qualquer pessoa que lê o meu blog e queira ajudar. O sistema é simples: eu te dou um login e senha no meu FTP e você desenvolve o que você conseguir (postando sempre que você muda uma letra o novo resultado, para que depois outra pessoa pegue e possa continuar).

Atualizado

O Renato deu uma idéia legal aí num comentário que é hospedar o troço em alguns desses sites de projetos de software livre e usar CVS pro desenvolvimento. Acho que realmente faz sentido, eu não tinha pensado nisso… Hehehe… Vou criar algo a respeito e depois eu publico aqui!

Se você for uma dessas pessoas dispostas, gostaria de pedir que você note alguns detalhes na construção dos meus arquivos:

  • Tabulação é feita com “tabs”.
  • As classes não imprimem nada na janela.
  • Mesmo os arquivos não imprimem nada também, eles imprimem para a variável $buf.
  • Não vale mexer nos arquivos config.php, index.php, ajax.php, scripts.js.php e style.css (por favor, deixe toda a parte de client-side, Ajax e configurações globais para mim :D ).
  • Todas as coisas que você passar para a variável $buf não podem conter texto. (Se você quer escrever qualquer coisa além do que foi retornado do banco de dados, deve criar uma variável $LANG[‘NOMEDAVAR’] no arquivo lang/pt_BR.php e lang/en_US.php
  • Se você não souber programar mas estiver afim de traduzir o projeto para alguma língua, me dê seu nome que quando tiver pronto eu vou querer muito sua ajuda.
  • Se você não quiser traduzir e nem souber programar, colabore com idéias de coisas que você acha legal o projeto ter (o que falta no Flickr que seria legal os programadores colocarem, ou sei lá…)

Espero que todos tenham entendido o espírito. Me mandem e-mail com sugestões e quem puder ajudar, ajude. Quem quiser dar um nome ao projeto, pode me sugerir também! Tenho certeza que um software livre desenvolvido pela comunidade para um fim que ainda não existe algo parecido (alguém conhece algum software livre de álbum de fotos que faça tudo que o Flickr faz?) fará bastante sucesso e será bem aceito ao menos pelos programadores (grande parte deles usa o Flickr mas tem um servidor legal que suporta PHP e GD).


Agora vamos voltar ao blog.

Fiquei um tempo sem postar justamente por causa desse projeto, que estou me esforçando para fazer o mais rápido possível. Também estou lendo “Java – Como Programar”. Tô gostando bastante da didática e gostando também da linguagem Java. No mais, não estou fazendo muita coisa. Estou indo trabalhar todos os dias a tarde, viajei final de semana para Florianópolis e agora que meu primo foi embora, minha casa está bem vazia (o que é ótimo! :) )

O Poder do Ajax

ATENÇÃO: Este conteúdo foi publicado há 12 anos. Eu talvez nem concorde mais com ele. Se é um post sobre tecnologia, talvez não faça mais sentido. Mantenho neste blog o que escrevo desde os 14 anos por motivos históricos. Leia levando isso em conta.

Ontem, pela primeira vez, desenvolvi um sistema em Ajax. Já vinha estudando há pouco mais de uma semana e hoje temos votação do Grêmio Estudantil no Colégio, e achei interessante fazer usando Ajax, e aproveitar algumas coisas como:

  • Todos usam Mozilla Firefox.
  • O servidor fica do lado dos computadores… É rede, não internet!

… para abusar de Ajax, já que eu podia fazer uma coisa que buscasse bastante no servidor e que só funcionasse no Gecko. O resultado ficou bem legal. Embora eu não tenha conseguido fazer um trechinho do script sem um IFRAME que atuliza sem parar, todo o esquema foi feito com JavaScript e aprendi umas coisas bem legais. Além disso, o formuláro ficou muito bonito, posicionado e desenvolvido em CSS. Os botões de radio estão com a propriedade display:none e os labels estão com opacity:0.5; Quando eu clico neles (onclick), eles deixam todos os outros com opacity:0.5 e se dão opacity:1. Quando o visitante clica no submit do formulário, o XmlHttp IMEDIATAMENTE pega os dados do servidor e joga na tela. Ficou uma coisa muito massa. E ainda aproveitei pra usar PNGs transparentes!

Não vou colocar o código aqui agora, ainda queria ajustar algumas coisas porque ontem fiz na pressa, mas confiram um screenshot! (o SS mais legal seria o do “Voto Confirmado”, quando um div com fundo PNG alpha aparece em cima de tudo, mas eu fiz um sistema de segurança para só quem tá dentro do Lab. de Informática poder votar – testando IPs – e agora estou em casa).

Screenshot da Votação do Grêmio

Ajax é muito power. Desenvolvendo com ele dá pra fazer umas coisas que antes eu nem imaginava… Agora tô estudando bastante JavaScript, porque com a parte de servidor/PHP não há problemas, mas nunca estudei muito o lado client-side (estudei tableless, mas não DOM/JavaScript!). Já li dois artigos do Elcio, do Tableless.com.br: Um sobre DHTML Crossbrowser e outro que é o conhecido Ajax para quem só ouviu falar. Agora estou acabando o segundo artigo dele sobre Ajax, Ajax: Encarando o Mundo Real. O bom é que a sintaxe das coisas no JavaScript são bem parecidas com as do PHP…


Tenho lido umas coisas desse cara e tô achando muito bom. Sugiro que quem goste de software livre ou quem quer aprender mais sobre ele, leia os artigos também. :)