#desenvolvimento, #projetos

No Comments – Extensão pro Chrome


Olá pessoas.

Após muito tempo sem posts resolvi escrever sobre uma extensão para o Chrome que fiz recentemente. Não irei me ater aos detalhes de como criar a extensão porque acredito que uma lida na documentação é suficiente para este fim.

Meu objetivo é discorrer sobre a motivação para criá-la e os recursos que utilizei.

Alguns sabem que a Web 2.0  trouxe a possibilidade dos usuários colaborarem com o conteúdo publicado através da inclusão de comentários, avaliações, personalização e compartilhamento. A ideia é linda mas o fato é que na maioria dos sites os comentários não adicionam nenhum valor ao conteúdo.

Hoje em uma lista de comentários é raro não ter pelo menos um comentário escrito com o intuito de ofender alguém. Nos grandes sites de notícias do nosso lindo país é comum ver centenas de comentários que nos fazem desacreditar na humanidade.  Às vezes a gente nem quer ler mas acaba lendo involuntariamente ao navegar pela página. E neste caso eu concordo plenamente com a frase: “A ignorância é um dom”. E não, eu não estou sendo contra a liberdade de expressão, só acho que não sou obrigada a ler esses lixos certas opiniões.

Partindo daí eu procurei por alguma extensão, pro Chrome, que bloqueasse a visualização dos comentários. Encontrei algumas, testei mas não funcionaram exatamente como eu queria e por isso eu resolvi desenvolvê-la :D.

O objetivo da extensão é bem simples: ocultar todos os comentários de todas as páginas assim que a página for carregada. Como um plus eu adicionei a possibilidade de reverter o processo porque apesar de tudo ainda tem alguns casos que queremos ver os comentários, mesmo que seja só para rir ou passar raiva.

Talk is cheap. Show me the code.

Torvalds, Linus

Então vamos ver como essa tal extensão foi feita, né.

Para que o seu código seja visto como uma extensão você precisa adicionar um arquivo chamado manifest.json que conterá as definições das propriedades.

{
  ...

  "background": {
    // Define qual é o JS principal da extensão.
    "scripts": ["background.js"]
  },

  "icons": {
    // Define o ícone exibido na lista de extensões (chrome://extensions).
    "128": "icon128.png";
  },

  "browser_action": {
    // Define o ícone exibido na omnibox.
    "default_icon": "icon.png"
  },

  "content_scripts": [ {
    // Define quais JS serão utilizados pela extensão.
    "js": [ "jquery-2.0.3.min.js", "functions.js" ],
    // Define para quais sites a extensão será carregada.
    "matches": [ "http://*/*", "https://*/*" ],
    // Define para quais sites a extensão NÃO será carregada.
    "exclude_matches": [ "https://*.github.com/*" ]
  }]

  ...
}

Como definimos o arquivo background.js como JS principal, ele será executado assim que a extensão for carregada.

// Adiciona o ouvinte para o clique no ícone da extensão.
chrome.browserAction.onClicked.addListener(function(tab) {
  // Define qual JS será executado quando receber o clique.
  chrome.tabs.executeScript(tab.id, {file: 'onclick_script.js'});
});

O arquivo onclick_script.js contém apenas uma verificação para identificar se os comentários serão exibidos ou ocultados no momento em que receber o clique.

if (show){
  show = false;
  showComments();
} else {
  show = true;
  hideComments();
}

E a ~~mágica~~ toda está acontecendo no arquivo functions.js. Aqui eu utilizei o jQuery para facilitar a vida juntamente com este sagaz código que seleciona os elementos utilizando expressão regular. A intenção era encontrar todos os elementos que tivessem nos atributos id e class o conteúdo coment(ario) ou comment. Por fim eu adicionei também um critério para buscar pelos comentários que utilizam o Disqus.

function showComments() {
  // Percorre os elementos encontrados exibindo-os.
  jQuery.each(elementsToShowById, function() {
    $(this).show();
  });
}

function hideComments() {

  var disqusExpression = '.*disqus_thread.*';
  var commentExpression = '.*[Cc]o(m|mm)ent.*';

  getVisibleElements('id', commentExpression);
  getVisibleElements('class', commentExpression);
  getVisibleElements('id', disqusExpression);

  // Percorre os elementos encontrados ocultando-os.
  jQuery.each(elementsToShowById, function() {
    $(this).hide();
  });
}

function getVisibleElements(attribute, expression) {
  // Seleciona os elementos pela expressão regular.
  $(':regex(' + attribute + ', ' + expression + ')').filter(function() {
    // Armazena apenas os elementos que estão visíveis.
    if ($(this).is(':visible')){
      elementsToShowById.push($(this));
    }
  });
}

Claro que esta é somente uma das inúmeras maneiras de fazer isto e que pretendo continuar evoluindo a extensão. De pronto já informo que a primeira melhoria a ser implementada é fazer a extensão ocultar os comentários do Youtube que não utiliza a palavra comments para definir seus elementos relacionados aos comentários.

É isso! Fiquem à vontade para instalar, testar e colaborar com a extensão.

Até breve.

PS.: Como eu disse tem casos que convém ler os comentários por isso mesmo que pareça contraditório eu leio e libero todos os comentários do blog, exceto os de spam ;).

Padrão
#desenvolvimento

Resolvendo o erro: Error calling method on NPObject


Olá pessoal.

Este é um daqueles post com soluções para os problemas do dia a dia. Recentemente eu precisei resolver o erro Uncaught Error: Error calling method on NPObject ocorrido em um projeto web desenvolvido com ASP.NET MVC3.

O tal erro acontecia ao submeter um determinado formulário. Mas só acontecia se em algum dos campos contivessem um & em seu conteúdo.

Este formulário continha um upload de imagem utilizando o Uploadify. E o erro acontecia no momento de executar a função uploadifyUpload() do plugin. Mais especificamente na linha abaixo:

document.getElementById(jQuery(this).attr('id') + 'Uploader').startFileUpload(ID, checkComplete);

Pesquisando e tentando solucionar este erro nada descritivo, identifiquei que o conteúdo do formulário era serializado antes de ser submetido. E quando isso acontecia o & era convertido para %26.

Então, resolvi substituir o & pelo unicode equivalente. Após serializar o objeto eu troquei o & pelo seu unicode \u0026 antes de chamar a função uploadifyUpload(). E o código ficou assim:

...
if ($('.uploadifyQueueItem').length > 0) {
   var conteudoForm= $("#id_form").serializeObject();
   var campo = conteudoForm['id_campo'];
   conteudoForm['id_campo'] = campo.replace('&', '\\u0026');
   $('.upload').uploadifySettings('scriptData', conteudoForm);
   $('.upload').uploadifyUpload();
}

Erro resolvido e formulário submetido normalmente. Tudo lindo, ou melhor, quase. O valor do campo está chegando com o unicode e precisamos voltar para o &.

No meu caso utilizando o ASP.NET MVC 3 recebo o conteúdo do formulário no método Create e faço a conversão lá mesmo:

[HttpPost]
public ActionResult Create(ModelQualquer modelQualquer, HttpPostedFileBase Filedata) {

   modelQualquer.Atributo = modelQualquer.Atributo.Replace("\\u0026", "&");
   ...
}

Agora sim, ta certo.

A solução foi bem idiota boba e deve ter umas 1000, ou mais, maneiras melhores de se resolver. O mais chatinho foi encontrar onde realmente estava o problema, já que o erro não diz nada muita coisa.

É isso, galera. Espero que possa ser útil e fiquem a vontade para postar outras soluções nos comentários.

Até breve 😉

Padrão
#desenvolvimento

Primeiro contato com Node.js


Olá pessoal.

Neste post vamos ver um pouquinho sobre como o Node.js funciona e como utilizá-lo no Windows. Para quem nunca ouviu falar sobre Node.js, ou quem ainda não sabe ao certo para que ele serve, recomendo a leitura deste post para que fique claro o que é o Node.js realmente é.

Node.js

Node.js

A utilização no Windows é feita de forma bem simples, sendo necessário instalar somente o Node.js que pode ser baixado aqui. Após baixar prossiga a instalação normalmente clicando em Next, Next e Finish 😉

Pronto o Node.js está instalado! Uma entrada de menu para Node.js será criado no menu Iniciar do Windows, porém não é através deste prompt que os códigos serão executados. Os comandos para executar os arquivos .js serão feitos no cmd do Windows.

Então, para fazer o famoso Hello World é preciso criar um arquivo, como por exemplo, teste.js e acrescentar a linha de código abaixo:

console.log('Hello World');

Salve seu arquivo na Área de trabalho, abra o cmd do Windows e acesse a pasta onde o arquivo foi salvo. E execute o comando:

node teste.js

Com isso deverá aparecer “Hello World” no seu cmd. Até aqui nada de muito novo, certo?!

Na página principal do Node.js existem dois trechos de códigos para os primeiros testes. Aqui iremos analisar o primeiro trecho responsável por criar um servidor web que fica esperando o recebimento das requisições HTTP. Vejamos o código:

 var http = require('http');

/*
 * O método createServer() cria e retorna uma nova instância de um webserver baseado no protocolo HTTP.
 * Este método recebe como parâmetro os objetos request e response.
 */
 http.createServer(function (req, res) {

   // Acresenta ao cabeçalho do response o content-type do retorno que será enviado para o browser.
   res.writeHead(200, {'Content-Type': 'text/plain'});

   // Acrescenta ao response o texto que será exibido no browser.
   res.end('Hello World\n');

   // Após a criação do web server é definido a porta e o IP que o server escutará.
 }).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');
 

Substitua o código do arquivo teste.js pelo código acima e execute-o no cmd:

node teste.js

No cmd deverá exibir a mensagem Server running at http://127.0.0.1:1337/, se exibir abra o seu navegador e acesse o endereço http://127.0.0.1:1337/. Então será exibida a mensagem Hello World na página. Isto significa que o web server criado está ativo e escutando as requisições HTTP.

Por enquanto é isso. Espero que possa ser esclarecedor para quem, assim como eu, tem interesse em conhecer o Node.js. Também pretendo postar, em breve, mais conteúdos sobre Node.js.

Até breve 😉

Padrão
#desenvolvimento, #prosa

Estudo para certificação 70-480


Olá pessoal.

Para quem ainda não sabe, a Microsoft liberou alguns vouchers para a prova de certificação 70-480 – Programming in HTML5 with JavaScript and CSS3. E como o conteúdo já era foco dos meus estudos resolvi fazer a prova também.

Criei um projeto no GitHub para poder compartilhar os links, materiais, resumos e códigos que forem úteis para quem tiver interesse em fazer a prova. E se você também estiver estudando, sinta-se encorajado(a) em fazer um fork do projeto e submeter seu pull request 😉

Link do projeto: https://github.com/monteirobrena/estudo_70-480

Link da página do projeto: http://monteirobrena.github.com/estudo_70-480

Até breve.

Padrão
#desenvolvimento

Como adicionar botões de compartilhamento de redes sociais – Google Plus


Olá gente.
Agora iremos implementar o compartilhamento pelo Google Plus para isto iremos adicionar o código abaixo no arquivo index.html.haml:

/ Botão de compartilhamento pelo Google Plus.
.span
  %g:plusone{:annotation => "none", :size => "medium"}
  :javascript
    (function() {
      var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
      po.src = 'https://apis.google.com/js/plusone.js';
      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
    })();

Assim como o Facebook, o Google Plus não permitiu o compartilhamento devido a aplicação está rodando localmente. Você pode publicar sua aplicação no Heroku para poder testar. Acesse este post e veja como realizar o deploy da aplicação no Heroku.

Para mais detalhes sobre o button share do Google Plus acesse aqui.

Com isto terminamos a série de posts sobre compartilhamento através das redes sociais. Espero que seja útil.

Até breve 😉

Padrão
#desenvolvimento

Como adicionar botões de compartilhamento de redes sociais – Facebook


Olá pessoal.
Neste post iremos implementar o compartilhamento pelo Facebook utilizando um projeto RoR com HAML e Javascript. Com projeto criado iremos adicionar o código abaixo no arquivo index.html.haml:

/ Botão de compartilhamento pelo Facebook.
.span
  .fb-send{"data-font" => "arial", "data-href" => "http://#{request.host}:#{request.port}#{request.fullpath}"}
  #fb-root
    :javascript
      (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
        fjs.parentNode.insertBefore(js, fjs);
      }(document, 'script', 'facebook-jssdk'));

Este botão do Facebook irá compartilhar o link da sua página que será formado por este código:

http://#request.host:#request.port#request.fullpath

Onde:
#{request.host} – Retorna o host da aplicação.
#{request.port} – Retorna a porta.
#{request.fullpath} – Retorna o caminho da página composto também pelas pastas.

Observação, o Facebook não permitiu o compartilhamento devido a aplicação está rodando localmente. Você pode publicar sua aplicação no Heroku para poder testar. Acesse este post e veja como realizar o deploy da aplicação no Heroku.

Para mais detalhes sobre o button share do Facebook acesse aqui.

Até breve 😉

Padrão
#desenvolvimento

Como adicionar botões de compartilhamento de redes sociais – Linkedin


Olá leitores.
Neste post iremos implementar o compartilhamento pelo Linkedin utilizando um projeto RoR com HAML e Javascript. Com projeto criado iremos adicionar o código abaixo no arquivo index.html.haml:

/ Botão de compartilhamento pelo Linkedin.
.span
  %script{:src => "//platform.linkedin.com/in.js", :type => "text/javascript"}
  %script{"data-url" => "http://#{request.host}:#{request.port}#{request.fullpath}", :type => "IN/Share"}

Este botão do Linkedin irá compartilhar o link da sua página que será formado por este código:

http://#request.host:#request.port#request.fullpath

Onde:
#{request.host} – Retorna o host da aplicação.
#{request.port} – Retorna a porta.
#{request.fullpath} – Retorna o caminho da página composto também pelas pastas.

Assim como o Twitter, o compartilhamento pelo Linkedin é super tranquilo. Para saber um pouco mais sobre o compartilhamento pelo Linkedin acesse a documentação disponível aqui.

Até breve 😉

Padrão