Bom finalmente chegamos ao terceiro artigo da série sobre bookmarklets. A intenção inicial era criar um bookmarklet que automatizasse a digitação do e-mail e senha no login do Google/Gmail. Porém, depois de uma avaliação, ficou claro o risco que isso geraria para quem utiliza a sincronização do Chrome. Em vez do bookmarklet prometido, vamos criar outro que talvez seja mais útil.
Antes de começar, não deixa de ler os artigos anteriores. O primeiro artigo é importante para entender o que são bookmarklets e como utilizá-los. No segundo artigo é dado um exemplo funcional para o preenchimento de formulários. Muito útil no desenvolvimento de back-ends de formulários, já que evite que seja necessário preencher os campos do formulário repetidamente para testar o back-end. Dito isso, vamos ao projeto deste artigo.
Quem utiliza o Firefox para desenvolvimento de sites, já deve conhecer a extensão Firebug. Esta extensão oferece uma grupo de recursos utilíssimos para o desenvolvedor. Um desses recursos, é a marcação dos elementos da página, criando linhas de borda, o que é muito útil no desenvolvimento de front-ends. No Chrome, eu ainda não encontrei uma extensão que faça isso de forma satisfatória, então vamos criar um bookmarklet que gera o mesmo resultado.
Antes de mais nada. Este bookmarklet é um exemplo do que pode ser feito para ajudar o desenvolvedor. É um projeto bem simples mas que pode ser modificado e se tornar mas sofisticado. Então vamos a ele.
Sim, CSS
Neste projeto, vamos criar um Javascript que irá “embutir” um bloco CSS no head do documento. Esse bloco CSS, tem as regras que criar as bordas coloridas nos elementos de estrutura do documento, como por exemplo DIVs, HEADERs e FOOTERs. Sendo assim, a primeira coisa a fazer é definir o CSS. Lembrando que este pode ser alterado de acordo com as necessidades.
div { outline: 1px solid #FF00FF !important; } header { outline: 1px solid #FFDD00 !important; padding: 1px !important; } footer { outline: 1px solid #993399 !important; padding: 1px !important; } nav { outline: 1px solid #0066CC !important; padding: 1px !important; } dd, dl, dt, ol, ul { outline: 1px solid #468847 !important; } form, table { outline: 1px solid #3a87ad !important; }
Com o CSS definido, vamos guardá-lo em uma variável como uma string para podermos utilizá-lo no Javascript.
var css = 'div { outline: 1px solid #FF00FF !important; } ' + 'header { outline: 1px solid #FFDD00 !important; padding: 1px !important;} ' + 'footer { outline: 1px solid #993399 !important; padding: 1px !important; } ' + 'nav { outline: 1px solid #0066CC !important; padding: 1px !important; } ' + 'dd, dl, dt, ol, ul { outline: 1px solid #468847 !important; } ' + 'form, table { outline: 1px solid #3a87ad !important; } ';
Variável css definida, vamos ao elemente style. Como dito mais acima, o Javascript vai “embutir” um bloco CSS no head do documento. Isso será feito dinamicamente com a inclusão de um novo tag style dentro do head. Para que isso seja possível, é necessário a criação de um objeto elemento do tipo style no Javascript. Vamos chamar este objeto de style.
var style = document.createElement('style');
Mais a frente vamos incluir o CSS e para incluir o novo elemento style no head do documento.
Nodes do documento
Agora precisamos criar um array contendo todos os elementos style da página. Este array irá conter todos os nodes do DOM do tipo style. Um nodo é um objeto relacionado a cada elemento do documento, então teremos todas a propriedades e métodos DOM do elemento. Iremos usar este array para verificar se o nosso CSS já está embutido no head do documento. Se já estiver, vamos removê-lo. Assim teremos como habilitar e desabilitar as bordas. Vamos usar o método from do objeto Array e o método getElementsByTagName do objeto document, que ira pegar todos os nodes do tipo style do DOM (Document Object Model), e guardá-los no array el_style.
var el_style = Array.from(document.getElementsByTagName("style"));
Embutindo o CSS
Chegamos ao ponto onde embutimos o CSS no documento. Vamos criar um função para isso.
var loadCSS = function(id,css) { style.setAttribute('id', id); document.getElementsByTagName("head").item(0).appendChild(style); style.innerText = css; };
Esse função recebe dois parâmetros. O primeiro, uma string com um identificados para o elemento style. É o valor que será atribuído ao atributo id do elemento. O segundo parâmetro é o CSS, e aqui vamos passar o valor da variável css.
Na primeira linha de código da função, atribuímos o valor do parâmetro id ao atributo id do elemento style. Na segunda linha, definimos o conteúdo no elemento style, inserindo o valor da variável css no dentro elemento. E finalmente, na terceira linha, criamos o novo elemento style dentro do head do documento usando o objeto style criado anteriormente.
Agora o principal
Aqui encontramos o bloco principal do nosso Javascript. É aqui onde tudo acontece.
A primeira coisa a fazer, é verificar se já existe algum elemento style no documento verificando o tamanho ou o número de elementos do array el_style. Se o tamanho do array for menor ou igual que zero, incluímos o nosso novo elemento executando a função loadCSS() sem fazer nenhum outro tipo de crítica.
Se o tamanho do array el_style for maior que zero, vamos varrer todo o array verificando o valor do atributo id de cada node. Se o id for igual a “blocked”, que é o id no nosso elemento style, definimos o valor da variável k para zero e guardamo o node na variável nd, lembrando que o node é o objeto relacionado ao elemento style.
Já identificamos se o nosso CSS já faz parte do documento. Agora vamos à parte onde determinamos se as bordas devem ser ativadas ou desativadas.
Vamos usar a variável k para sabermos se devemos ativar ou desativar as bordas. Se o valor de k for igual a zero, isso indica que o nosso CSS já incluído no documento. Sendo assim, as bordas devem ser desativadas. Então usamos o método remove do objeto nd para remover o node do DOM, fazendo com que o nosso CSS seja removido do documento e desativando as bordas. Se o valor de k for igual a 1, significa que o nosso CSS ainda não faz parte do documento, então executamos a função loadCSS() para “embutir” um novo elemento style no head do documento como o nosso CSS.
if(el_style.length<=0) { loadCSS('blocked',css); } else { k = -1; for(i=0; i<=el_style.length-1; i++) { id = el_style[i].getAttribute("id"); if(id=='blocked') { k = 0; nd = el_style[i]; break; } else { k = 1; } } if(k==1) { loadCSS('blocked',css); } else { nd.remove(); } }
Finalizando
Temos agora o código Javascript do no nosso bookmarklet completo.
var css = 'div { outline: 1px solid #FF00FF !important; } ' + 'header { outline: 1px solid #FFDD00 !important; padding: 1px !important;} ' + 'footer { outline: 1px solid #993399 !important; padding: 1px !important; } ' + 'nav { outline: 1px solid #0066CC !important; padding: 1px !important; } ' + 'dd, dl, dt, ol, ul { outline: 1px solid #468847 !important; } ' + 'form, table { outline: 1px solid #3a87ad !important; } '; var style = document.createElement('style'); var el_style = Array.from(document.getElementsByTagName("style")); var loadCSS = function(id,css) { style.setAttribute('id', id); style.innerText = css; document.getElementsByTagName("head").item(0).appendChild(style); }; if(el_style.length<=0) { loadCSS('blocked',css); } else { k = -1; for(i=0; i<=el_style.length-1; i++) { id = el_style[i].getAttribute("id"); if(id=='blocked') { k = 0; nd = el_style[i]; break; } else { k = 1; } } if(k==1) { loadCSS('blocked',css); } else { nd.remove(); } }
Conclusão
E com isso finalizamos o nosso artigo e essa série de três artigos sobre bookmarklets. Como disse antes, os projetos desta série são bem simples e servem apenas para demonstrar o poder dos bookmarklets.
Neste último projeto, usamos um bookmarklet para incluir um CSS que marca os elementos principais estruturais da página com bordas. Outros CSS podem ser incluídos para outros elementos HTML. Basta para isso, criar outros bookmarklets utilizando o mesmo código Javascript, alterando o valor da variável css e o id do elemento style.
Baixo deixo alguns outros CSS que podem ser úteis e sugestões de ids.
id tipografia
var css = 'h1,h2,h3,h4,h5,h6 { outline: 1px solid #4BFF51; background-color: #E7FFED;} ' + 'p { outline: 1px solid #3748FF; background-color: #EFF3FF; }';
id tables
var css = 'table { border: 1px solid #b94a48 !important; border-collapse: separate !important; } ' + 'table table { border-color: #468847 !important; } ' + 'table table table { border-color: #3a87ad !important; } ' + 'table table table table { border-color: #b94a48 !important; } ' + 'table table table table table { border-color: #468847 !important; } ' + 'table table table table table table { border-color: #3a87ad !important; }';
id tablecells
var css = 'table { border-collapse: separate !important; } ' + 'td, th { border: 1px solid #b94a48 !important; } ' + 'table table td, table table th { border-color: #468847 !important; } ' + 'table table table td, table table table th { border-color: #3a87ad !important; } ' + 'table table table table td, table table table table th { border-color: #b94a48 !important; } ' + 'table table table table table td, table table table table table th { border-color: #468847 !important; } ' + 'table table table table table table td, table table table table table table th { border-color: #3a87ad !important; }';
id before
(esta exibe o nodeName dos elementos)
var css = 'address:before, blockquote:before, h1:before, h2:before, h3:before, h4:before, h5:before, h6:before, p:before, pre:before { background: #b94a48 !important;} ' + 'dd:before, dl:before, dt:before, ol:before, ul:before { background: #468847 !important; } ' + 'div:before, form:before, table:before { background: #3a87ad !important; } ' + 'address:before { content: "<address>" !important; } ' + 'blockquote:before { content: "<blockquote>" !important; } ' + 'div:before { content: "<div>" !important; } ' + 'dl:before { content: "<dl>" !important; } ' + 'form:before { content: "<form>" !important; } ' + 'h1:before { content: "<h1>" !important; } ' + 'h2:before { content: "<h2>" !important; } ' + 'h3:before { content: "<h3>" !important; } ' + 'h4:before { content: "<h4>" !important; } ' + 'h5:before { content: "<h5>" !important; } ' + 'h6:before { content: "<h6>" !important; } ' + 'ol:before { content: "<ol>" !important; } ' + 'p:before { content: "<p>" !important; } ' + 'pre:before { content: "<pre>" !important; } ' + 'table:before { content: "<table>" !important; } ' + 'ul:before { content: "<ul>" !important; }';
Espero que os artigos sejam úteis e que acrescente um pouco mais pouco mais a carga de conhecimento dos colegas desenvolvedores. Até o próximo e não deixe de curtir a nossa página no Facebook.