JS, e a batalha pelo controle da tecnologia web

Há algum tempo atrás, eu escrevi aqui sobre a nova especificação do Javascript, oficialmente conhecida como ECMAScript 4.0. Esta versão pretendia modernizar a linguagem, que estava congelada desde 1999 na versão 3.0 (também conhecida como Javascript 1.5). Na semana passada, esta versão foi oficialmente abandonada: o motivo foi uma longa batalha, que colocou em campos opostos alguns grandes players da internet mundial.

Entre as empresas que apoiavam a versão 4.0, estavam Google, Mozilla (que inclusive criou o projeto Tamarin, cujo objetivo foi criar uma implementação de um engine JS 100% compatível com esta nova especificação), e Adobe. Esta última tinha um interesse especial nesta nova especificação, já que internamente, seus engenheiros chamavam a nova versão de ActionScript 3.0.

ActionScript é, como todos sabem, a linguagem utilizada para desenvolver programas em Flash, tecnologia amplamente adotada na Internet. A Adobe tinha como planos fazer com que a nova especificação de Javascript fosse compatível com a sua própria linguagem de script. Conseguiria assim dois feitos: primeiro, rebateria as críticas daqueles que a acusavam de querer tornar a web um mundo proprietário. Segundo (e talvez o feito mais importante), unificaria as duas mais populares tecnologias  das duas tecnologias da Internet moderna: Flash e a linguagem que se tornou o pilar básico do AJAX e por consequência da tão falada Web 2.0.

Do outro lado desta batalha, estava nada menos do que a poderosa Microsoft, que luta para se firmar como uma empresa com um real poder de fogo e de influência sobre a grande rede mundial. Oficialmente, o argumento é de que a nova especificação representa uma evolução muito radical em relação à versão anterior, e que o melhor seria focar em desenvolver uma versão 3.1 inicialmente, e depois trabalhar em uma versão mais modesta da especificação 4.0. Devo dizer que concordo com a opinião de que a nova especificação era muito complexa, introduzindo uma quantidade bastante grande de conceitos e palavras chaves.

Mas a realidade é que a Microsoft, representada por Allen Wirfs-Brock, não quer ver uma outra empresa impor sua tecnologia como standard da Internet. E por enquanto conseguiu, como mostra o este trecho do comunicado oficial de Breidan Eich, membro do comitê executivo para definição da ECMAScript:

1. Focus work on ES3.1 with full collaboration of all parties, and target two interoperable implementations by early next year.
2. Collaborate on the next step beyond ES3.1, which will include syntactic extensions but which will be more modest than ES4 in both semantic and syntactic innovation.
3. Some ES4 proposals have been deemed unsound for the Web, and are off the table for good: packages, namespaces and early binding. This conclusion is key to Harmony.
4. Other goals and ideas from ES4 are being rephrased to keep consensus in the committee; these include a notion of classes based on existing ES3 concepts combined with proposed ES3.1 extensions.

Beleza booleana

Até há muito pouco tempo atrás, expressões booleanas para mim eram apenas uma questão de verdadeiro ou falso, ifs, whiles e do..whiles. Nesta época, eu ria quando encontrava trechos de códigosdo estilo

boolean b = true; if (b == true){...}.

A vida era simples, linda e limitada.

Daí eu comecei a brincar seriamente com javascript e python, e descobri que existe muito mais coisas entre o céu e as funções booleanas do que poderia sonhar minha vã filosofia. Neste mundo novo, expressões booleanas podem ser muito mais do que apenas true ou false: elas podem ser formas extremamente elegantes e compactas para atribuição de valores.

Vamos por partes. Em Java, apenas variáveis do tipo booleanas ou expressões que retornem variáveis do tipo booleanas (maior que, menor que, igual a, contém, …) podem ser utilizadas em expressões booleanas. Uma construção do tipo if(1) não funciona.

Em linguagens de script, qualquer objeto pode ser avaliado como uma expressão booleana. Em Python por exemplo, a seguinte regra é aplicada: valores False (booleano), 0, “”, e None (valor nulo) são avaliados como falso; qualquer outro valor é avaliado como verdadeiro. A expressão (1 and 2) seria avaliada como true por exemplo.

Um outro ponto interessante em Python e Javascript é que expressões booleanas não retornam simplesmente True ou False: elas retornam o valor de um dos objetos da expressão. Uma expressão com AND retorna o último valor da expressão caso todos elementos sejam avaliados como verdadeiros, ou retorna o primeiro valor que fez com que toda a expressão fosse avaliada como falsa. Por exemplo: 1 and "miguel" and 2 retorna 2, porque todos os elementos da expressão são verdadeiros, e portanto a expressão toda é verdadeira. Já 1 and 0 and 2 retorna 0, uma vez que este é o primeiro elemento avaliado como false. E como todos sabemos, se um elemento é falso, a expressão toda é falsa.

No caso de uma expressão OR, ela retorna o primeiro elemento que for avaliado como verdadeiro, ou o último elemento da expressão caso todos os anteriores sejam avaliados como falsos. Por exemplo (1 or 2) retorna 1, e (0 or "") retorna “”.

Ótimo. Então como podemos usar isso para escrever expressões compactas, úteis e elegantes? Eis algumas sugestões:

  • Valor default para uma variável: OR pode ser usado para garantir que caso um parâmetro seja passado com valor nulo para uma função por exemplo, ele receba um valor default:
    var v = param || “default”
  • Expressões ternárias: o uso de OR e AND pode criar uma função ternária em linguagens que não possuem esta construção (Python por exempl0):
    var v = (condicao AND valor1) OR valor 2

Aproveito pra levantar um ponto: estilo compacto é algo bom ou ruim? Um argumento muito utilizado contra expressões compactas como as descritas acima é que prejudica a legibilidade. De fato, pode ser mais difícil de ler à primeira vista. Mas mesmo construções mais verborrágicas podem ser dificeis de serem lidas: tudo depende de quão treinado é o olho e o cérebro do leitor. Portanto, eu acho que é apenas uma questão de estar acostumado a ler código de qualidade.

Links sobre Regex

Para quem ainda tem dúvidas sobre a utilidade de Regex, dois links do mesmo blog:

10 Reasons to Learn and Use Regular Expressions

e
Levels of JavaScript Regex Knowledge

Dica: Ajax, JSON e IE 6

Esta dica é bem pontual, e talvez resolva a vida de no máximo duas pessoas. Mas o problema aqui abordado me custou minutos preciosos, e portanto vou aproveitar o fato de ter um blog para compartilha-lo com vocês. Sem contar que faz um bom tempo que eu não escrevo nada mais técnico.

Cenário básico: aplicação web com interface contendo vários trechos que necessitam de comunicação assíncrona com o servidor (a.k.a Ajax). Por motivos de projeto, a resposta vem em formato JSON (para resumir, eu tive que substituir DWR por Prototype, e para ser o menos intrusivo possível na aplicação, usei o mesmo formato de transmissão de dados do framework).

Dentre os vários dados recebidos do servidor, um deles é uma estrutura de dados representando um endereço:

{cidade: {id: 1, nome: "Sampa"}, estado: {id: 1, nome: "SP"}, pais: {id: 1, nome: "Brasil"},}

Muito bem. Para transformar este trecho em um objeto tratável pelo javascript como uma estrutura de dados, eu usei o comando var data = eval("("+response.responseText+")"), onde response é o objeto de resposta da requisição.

No Firefox, o sistema funcionou maravilhosamente bem. No IE 6, pra variar, necas. Não testei no IE 7.

O problema foi a última vírgula antes da última chave. O uso de chaves indica que estou descrevendo um dicionário (contendo pares chave: valor). Ao colocar uma vírgula no final, o IE entende que teremos mais um par à frente, e reclama ao encontrar uma chave. Tirei a virgula, e tudo funcionou perfeitamente.

________________________________________

Adendo feito algumas horas depois: justiça seja feita, o IE segue a especificação formal do JSON ao pé da letra. Vendo o diagrama da sintaxe do JSON no site json.org, vi que após uma virgula deve haver um par chave:valor. MEA CULPA.

Passagem de parâmetros elegante em Javascript

Suponha a seguinte definição de função em Javascript:

function foo(p1, p2,){
...
}

As seguinte chamadas são válidas: foo(), foo(1), foo(1, 2) e foo(1, 2, 3). No primeiro caso, a função foo será chamada e as variáveis terão todas valor null. No segundo caso, p1 terá valor 1 e p2, null. No segundo caso, p1 e p2 terão valor 1 e 2 respectivamente. No terceiro também, e o valor 3 poderá ser acessado pela variável local arguments (leia o meu post sobre argumentos variáveis em Javascript para entender esta funcionalidade).

Ou seja: uma declaração de função em javascript é extremamente flexível. Uma função sempre pode receber um número variável de parâmetros. A definição de parâmetros formais da função apenas define um nome a priori para estes valores.

Este flexibilidade toda seria ótima se Javascript, assim como Python, permitisse a identificação dos parâmetros na chamada da função. Por exemplo, se eu quisesse chamar foo apenas com o valor da variável p2, eu poderia chamar foo(p2=2). Infelizmente isto não funciona: Javascript vai preenchendo as variáveis na ordem em que elas aparecem na definição . Portanto se eu quisesse apenas atribuir um valor a p2, teria que chamar foo(null, 2). Além disso, a linguagem não permite definir valores defaut para os parâmetros.

Uma forma elegante de contornar esta limitação da linguagem, utilizando um recurso extremamente útil implementado nativamente, e de quebra permitir que as variáveis sejam identificadas na chamada ( o que facilita muito a leitura e manutenção do código, quando chamamos funções que aceitam muitos parâmetros) é criar funções que recebam sempre apenas um argumento: um dicionário.

Eis uma nova implementação de foo que recebe os mesmo 3 parâmetros, utilizando um dicionário, e que de quebra define valores default para cada um deles caso o usuário não defina:


function foo(params){
var p1 = params.p1 || 1;
var p2 = params.p2 || 2;
var p3 = params.p3 || "string"
}

Neste caso, caso eu queira chamar foo apenas com os valores de p2 e p3, eu executo foo({p2:2, p3: 3}). Simples assim.

A construção var p1 = params.p1 || 1 utiliza propriedades das expressões booleana para determinar o valor. Em javascript, uma função OR retorna o valor do primeiro elemento que for avaliado como verdadeiro, ou o valor do último elemento avaliado caso todos sejam falsos. Os valores null, 0, false, undefined e “” (string vazia) retornam falso. Caso o parâmetro não seja definido pelo usuário na chamada da função, params.<nome do atributo> retorna null, e portanto o segundo valor da expressão booleana é atribuido à variável.

Quer aprender mais dicas avançadas de Javascript? Funções com argumentos variáveis em Javascript, Captura de teclas em Javascript - Parte 1, Captura de teclas em Javascript - Parte 2 e Concatenação eficiente de Strings em Javascript e AJAX em 20 minutos.

XML para quê? Conheça YAML, o primo esperto das linguagens de markup.

Conhece a anedota? Conta que um programador estava tentando resolver um problema: ele tinha um sistema que precisava manipular e enviar informação estruturada para outros clientes. Num instante de pura sagacidade, ele pensou “Já sei. Vou usar XML!”. No instante seguinte, de pura decepção, ele constatou: “Agora eu tenho dois problemas. Não bastasse meu problema original, eu vou usar XML.”

De todos os alfabetos gastos em tecnologias que construiam “em cima” do XML (XQuery, XPath, XSL, XML-RPC, X-Men, Xuxa, sei lá) não consigo lembrar de nenhum que traga algo novo. Parece que é o tipo de coisa que cai na categoria “problemas inventados pelos vendors de software para que eu possa continuar justificando lucros trimestrais de US$4 bilhões.”

Tudo que eu e o programador da anedota precisamos é de um sistema que possa passar informação de um jeito estruturado. Se puder ser facilmente lido como texto, tanto melhor. Ninguém merece ter que ficar editando arquivo CSV, não é mesmo?

Que tal a possibilidade de ver um registro de uma fatura num formato assim?

invoice: 34843

date   : 2001-01-23

bill-to: &id001

    given  : Chris

    family : Dumars

    address:

        lines: |

            458 Walkman Dr.

            Suite #292

        city    : Royal Oak

        state   : MI

        postal  : 48046

ship-to: *id001

product:

    - sku         : BL394D

      quantity    : 4

      description : Basketball

      price       : 450.00

    - sku         : BL4438H

      quantity    : 1

      description : Super Hoop

      price       : 2392.00

tax  : 251.42

total: 4443.52

Esse é um documento YAML, válido. Bonitinho, né? Pena que ninguém mais usa isso por aí… e de que adianta ser capaz de emitir algo assim, se ninguém é capaz de receber? Vou ter que continuar usando XML?
Não necessariamente. Especialmente se está mexendo com web e já ouviu falar de uma outra darling das notações de marcação, JSON.

JSON, essa você já deve ter ouvido falar. Seu browser mastiga isso com uma facilidade tremenda:

{"student": {

  "first name": "John",

  "last name": "Smith",

  "course": {

    "report": [

      {"Subject": "Math", "grade": "A"},

      {"Subject": "English", "grade": "C"},

      {"Subject": "Arts", "grade": "F"}]}}}

 }

É só pedir para o seu interpretador Javascript avaliar essa string, e você tem um objeto que pode processar, e apresentar um relatório lindo para os pais do John, que vão dar uma bronca nele por ele não largar do computador e não ter aprendido a desenhar flores em aquarela.

Deixa eu contar o pulo do gato: todo JSON válido também é YAML. A notação usada em JSON é usada para descrever inline collections em YAML. Se você tiver uma string que seja a representação de um objeto em JSON, ele será visto como um objeto pelo seu parser de YAML (escolha aqui seu parser, na sua linguagem/plataforma favorita).

O que se ganha com isso? Um exemplo: validação e manipulação de formulários. Que tal a possibilidade de não só validar os dados no cliente, mas também pegar os campos de um formulário, verificar se o objeto está consistente, transformar em uma string JSON (usando um emitter apropriado) e enviar para o servidor essa string? Depois, o seu parser de YAML vai te montar um objeto, o qual pode ser muito mais facilmente validado e verificado.

Para quem quiser fazer formulários onde campos podem ser livremente adicionados ou removidos, ou usar toneladas de AJAX em seu aplicativo web, a combinação JSON + YAML funciona e é uma mão na roda.

Funções com argumentos variáveis em Javascript

As vezes, é útil escrever funções ou métodos cujo número de argumentos é desconhecido a priori. O exemplo clássico funções de formatação de String.

printf("Olá, meu nome é %s, tenho %d anos e moro em %s", "Miguel", 27, "São Paulo")

No exemplo acima, sabemos que no mínimo teremos 1 argumento, que é a string a ser impressa. Mas não sabemos quantos elementos serão injetados na string final. Uma forma de contornar isso é passando os parâmetros em um vetor. A outra é usando um sistema de número de parâmetros variáveis.

Em Javascript, isto é possível utilizando a variável local arguments, existente dentro de cada função executada. Esta variável é um vetor que contém todos os parâmetros realmente passados na chamada da função. Exemplo de uso:

function foo(){
var sum = 0;
for (var i=0; i<arguments.length; i++ ) sum += arguments[i]:
return sum
}

O código acima recebe um número desconhecido de inteiros e retorna a soma destes.

foo(1) = 1;
foo(1,2,3) = 6
foo()=0;

AJAX em 20 minutos

Antes de mais nada, vamos ajustar certos conceitos.

AJAX = Asynchronous Javascript XML. Portanto, AJAX é basicamente uma técnica que consiste em fazer requisições HTTP de forma assíncrona para o servidor (Nota: AJAX não é uma tecnologia. É uma técnica. Quem disser que é uma tecnologia merece arder no fogo do inferno pela eternidade). Se você não sabe o que é uma requisição HTTP, sugiro dar uma olhada aqui. Não tem como escapar, é a base de tudo.

Fazer uma requisição assíncrona significa que o processo irá rodar por trás das cortinas, não interferindo no funcionamento da tela no navegador, ao contrário do que acontece em uma requisição normal. Quando executamos uma requisição síncrona no navegador (através de um link ou submetendo os dados de um formulário), toda a interface para de responder a eventos. Isto fica particularmente claro (e chato) quando a página é pesada e/ou a rede esta lenta.

As vantagens da técnica são óbvias: interfaces mais leves, suaves, muito próximas daquelas de aplicativos desktop.

Pré requisitos para conseguir mexer com AJAX? conhecer um pouco de Javascript, DOM HTML e conhecer pelo menos uma linguagem de programação server side.

Passo 1: Preparando o terreno

Para começar, uma má notícia: muito do trabalho normalmente feito pelo navegador quando submetemos um formulário com dados tem que ser feito pelo script javascript. Ou seja, tem que ser feito pelo desenvolvedor. Um deles é construir a string de requição. O formato da string é algo do tipo

chave1=valor1&chave2=valor2&…

Não existe muito segredo. O único cuidado a ser tomado é em relação aos caracteres especiais. Espaços, símbolos como &, =, caracteres acentuados e caracteres não ASCII devem ser convertidos para o formato Unicode. Em Javascript existem várias funções que fazem este tipo de conversão, mas o mais adequado é o par encodeURIComponent/decodeURIComponent.

O seu uso é muito simples: var string_codificada = encodeURIComponent(string_original).

Em caso de requisições muito longas, aconselho o uso de um StringBuffer, que torna o processo de contatenação de strings muito mais eficiente. Veja aqui como fazer isso.

Passo 2: enviando os dados para o servidor

Muito bem. Já temos uma string de requisição, agora precisamos enviar isto para o servidor. Para isso, existem 2 métodos: GET e POST .

  • O método GET envia os parâmetros na requisição (www.meusite.com?chave1=valor1&chave2&valor2…) e tem uma limitação de tamanho de 1024 bytes. É mais indicado para enviar parâmetros relacionados á busca de informações no servidor.
  • O método POST envia os parâmetros de forma separada, e não tem limitação de tamanho. É mais indicado para envio de dados de formulários, textos longos e dados que serão armazenados no servidor. Se os dados forem maiores que 4KB, alguns cuidados especiais devem ser tomados, como mostrado aqui.

Para executar a requisição, o primeiro passo é criar o objeto HTTPRequest:

var req;

if (window.XMLHttpRequest)

    req =  new XMLHttpRequest();

else if (window.ActiveXObject)

    req = new ActiveXObject('Microsoft.XMLHTTP');

else

    req =  new ActiveXObject('Microsoft.XMLHTTP2');

O código acima cria um objeto de requisição para Windows ou Firefox (eles são ligeiramente diferentes, apesar de terem interfaces de uso iguais). Com o objeto de requisição na mão, o próximo passo é definir a função que será chamada quando o resultado da requisição enviado pelo servidor estiver disponível:

req.onreadystatechange = minhafunc;

O uso desta função será explicado no próximo passo. Finalmente, o envio dos dados. Se o método usado for GET, a receita de bolo é

requestObject.open('GET', url, true);
requestObject.send(null);

Onde url = endereçodapagina?stringderequisicao. Se o método for POST, a receita de bolo é

requestObject.open('POST', url, true);

requestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

requestObject.setRequestHeader("Connection", "close");

if (parameters != null)

    requestObject.setRequestHeader("Content-length", parameters.length);

requestObject.send(parameters);

onde URL é apenas o endereço do servidor, e parameters contém a string de requisição. Muito bem, os dados foram enviados. Agora é esperar os dados voltarem, e irmos para o próximo passo.

Passo 3: obtendo a resposta

No passo 2, definimos o valor do atributo req.onreadystatechange. Esse atributo é uma função que será chamada pelo navegador para tratar a resposta. Uma forma de definir a função é

req.onreadystatechange= function(){

    //corpo da função vai aqui

}

Um ponto a ser ressaltado é que esta função pode ser chamada várias vezes, sem a resposta estar disponível ainda: a o processo passa por vários estados antes de estar pronto para processamento. Portanto é necessário testar o status do processamento. Isto pode ser feito com o seguinte código

req.onreadystatechange= function(){
if (req.readyState == 4){
if (req.status == 200){
//Resposta disponivel
}
}
}

O atributo readyState pode assumir 4 valores:

  • 0: requisição não inicializada
  • 1: conexão estabelecida
  • 2: requisição recebida
  • 3: processando
  • 4: requisição terminad, resposta pronta.

Já o atributo status fornece o status do protocolo HTTP. 200 significa OK.

Muito bem, temos a resposta. O último passo é processar o resultado. Para obter o DOM XML, basta executar req.responseXML. Para trabalhar com o conteúdo como se fosse uma sequência de texto, basta executar req.responseText. E para processar o resultado como JSON, basta executar eval(”(”+req+”)”).

Segue um exemplo completo de código que recebe um snippet HTML (um trecho de código em HTML) e atualiza o conteúdo de uma DIV com este código:

function atualizaDiv(){

    var req;

    if (window.XMLHttpRequest){

        req = new XMLHttpRequest();

    } else if (window.ActiveXObject){

       req =  new ActiveXObject('Microsoft.XMLHTTP');

    }else{

       req =  new ActiveXObject('Microsoft.XMLHTTP2');

    }    req.open('POST', url, true);

    req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');    req.onreadystatechange = function(){

        if (req.readyState == 4){

           if (req.status == 200){

               document.getElementById("minhaDiv").innerHTML=req.responseText;

               document.body.style.cursor = "default";

           }

        }

    }

req.send(params);

}

Em breve escreverei um post comentando sobre vantagens e desvantagens de se usar texto, XML ou JSON como resposta de uma requisição.

Caso esteja interessado em usar uma biblioteca simples para desenvolver sites com Ajax, ou queria ver exemplos de código escrito em Javascript, dê uma olhada na Juice Lib, uma biblioteca em Javascript que estou desenvolvendo. O código está em http://code.google.com/p/juicelib.

Quer aprender mais dicas avançadas de Javascript? Funções com argumentos variáveis em Javascript, Captura de teclas em Javascript - Parte 1, Captura de teclas em Javascript - Parte 2 e Concatenação eficiente de Strings em Javascript

Curso online de Javascript

Quem estiver procurando um curso minimamente estruturado de Javascript, que aborde conceitos interessantes da linguagem e não apenas formas de manipulação de DOM, aconselho este site: http://eloquentjavascript.net/.
Algo que me chamou a atenção foi o fato do curso abordar tópicos de cursos básicos de teoria de computação (raramente abordados quando se fala em Javascript) como estruturas de dados, heaps, árvores binárias, algoritmos de busca e expressões regulares. Este texto se encaixa na teoria de que Javascript é uma linguagem real de programação, e não apenas uma ferramentinha pra deixar páginas web mais dinâmicas.

Javascript é uma linguagem séria

Juro que eu gostaria de ter encontrado um título melhor para este post, mas não consegui. Pelo menos ele tem o mérito de ser conciso. Vamos ao que interessa…

No começo, desenvolver interfaces web em HTML era algo apenas para programadores. Difícil chamar aquilo de interfaces, eram na verdade documentos usando o conceito de hipertexto. Links, marcadores e afins era algo que apenas geeks conseguiam entender.

Com o tempo, rapidamente percebeu-se que geeks não tinham capacidade de fazer telas bonitas e atraentes. E daí, interfaces web viraram negócio de designers. Geeks eram ótimos para escrever scripts em Perl ou PHP server side. Mas designers não são geeks, e por isso criou-se a necessidade de se desenvolver aplicativos WYSIWYG (What You See Is What You Get), que permitem que pessoas criem telas sem a necessidade de escrever uma linha que seja de HTML. Com isto ganhamos telas lindas, mas códigos em geral horríveis. (É bem verdade que a qualidade dos códigos gerados melhorou muito nos últimos anos. Quem teve um dia o desprazer de ver o código gerado pelo Frontpage em 1999 ficaria muito positivamente espantado hoje em dia).

Neste contexto, apareceu o Javascript. Lançado pela Netscape, ele tinha como objetivo maior adicionar um pouco de interatividade nas páginas, sendo executados pelos navegadores nos clientes. Na época, interatividade significava basicamente validação de formulários e exibição de caixas de alertas e mensagens. Como interfaces eram desenvolvidas por designers e designers (em geral) não sabem programar, os códigos javascript criados eram péssimos. Muitas vezes, eram simplesmente gerados automaticamente pelos editores. E assim, Javascript ficou com a fama de ser uma linguagem ruim, não padronizada (IE e Netscape tinham/tem implementações diferentes) e de escopo reduzidíssimo.

E o Google chegou, e mostrou ao mundo as maravilhas do AJAX e das interfaces rápidas, eficientes, cada vez mais semelhantes a interfaces de aplicativos desktop, e as coisas mudaram. Havia a necessidade de se desenvolver interfaces cada vez mais complexas, com cada vez mais código. Não eram mais páginas web: passamos a criar aplicativos web. E aí, voltou a ser um assunto de geeks. E Javascript passou a ser olhada de forma diferente.

Hoje, Javascript foi padronizada (chama-se ECMAScript), e bibliotecas para desenvolvimento de interfaces AJAX pipocam todo dia (como por exemplo a minha Juice Lib) , livros e tutoriais passaram a ser escritos, regras de boa prática estão aparecendo e alguns passam a ver a linguagem com possibilidades maiores. Outro dia achei um artigo que fala que javascript já passou pelas fases de “precisamos de uma linguagem de script para páginas web”, “precisamos de um standard para esta linguagem”, “javascript afinal não é um brinquedo”, e que agora, estaríamos entrando na fase do

JAVASCRIPT É UMA LINGUAGEM DE PROGRAMAÇÃO

E a partir deste momento, é justo se perguntar: se javascript é uma linguagem de programação podemos então escrever aplicativos que não estejam forçosamente ligados ao escopo de uma página? Why not! Temos todos os elementos necessários para isso na linguagem. E inclusive, algumas experiências interessantes sendo lançadas.

Uma delas é o Rhino, interpretador de javascript escrito em Java. Outra é o Javascript on Rails, um porte do Ruby on Rails para javascript feito pelo Steve Yegge, rodando sobre o Rhino. Curioso saber que o motivo de ele ter feito este porte é o fato de precisar de algo como o Ruby On Rails, pra desenvolver projetos no Google (onde ele trabalha) mas ter a limitação de não poder utilizar Ruby (lá, as linguagens aceitas são Java, Python, C++ e Javascript).

[Aproveito para dizer que se alguem tiver interesse em me ajudar no desenvolvimento da Juice Lib, será muito bem vindo.]

 

Juice Lib 0.3 no ar!

Acabei de colocar no ar a versão 0.3 da Juice Lib. A grande novidade deste release são funções para manipular elementos HTML e formulários. Estas funcionalidades podem ser acessadas de duas formas: a primeira forma é via o pacote juice.html, como por exemplo a função juice.html.submit(form, handler), que submete um formulário via AJAX e processa o resultado na função handler, ou juice.html.block(element), que define o modo de display de um elemento da página como block.

A segunda forma utiliza uma versão modificada da classe String, que permite que elementos da página sejam referenciados diretamente através do seu ID ou TAG. A sintaxe é: “%nomedadiv” para acessar uma div específica ou “@nomedatag” para retornar uma lista de tags da página. Por exemplo, se eu quiser definir o modo de display da div div1 da página, eu executo ‘%div1′.block(). Caso eu queira aplicar a mesma função a todos os divs da página, executo ‘@div’.block().

Alguns operadores já foram incluidos na lib (block, none, visible, invisible, submit). Mas caso o usuário deseje aplicar um operador próprio, basta usar a função apply, passando como argumento uma função que recebe o elemento. Por exemplo

‘@span’.apply(function(x){x.style.backgroundColor=”#00FF00″});

muda a cor de fundo de todos os elementos SPAN da página.

É possível também obter uma referência a um elemento da página usando a função el. Por exemplo, ‘%minhadiv’.el() retorna um apontador para o elemento minhadiv. O comando ‘@div’.el() retorna um vetor de apontadores para os elementos DIV da página.

A versão 0.3 pode ser encontada em http://code.google.com/p/juicelib. Como sempre, comentários, sugestões e críticas são muito bem vindos.

Juice Doc

Uma versão preliminar da documentação da Juice Lib está disponível em http://code.google.com/p/juicelib/wiki/JuiceDoc

Juice Lib 0.1.2

Ontem coloquei no ar a versão 0.1.2 da Juice Lib. A grande novidade é o sistema de pooling com AJAX. Este sistema permite que uma requisição seja feita de tempos em tempo via XMLHTTPRequest para um endereço, e que o resultado seja processado em background.

Segue um exemplo de criação de objeto de pooling:

  • sched = new juice.rpc.AjaxScheduler(”http://minhaurl.com”,{response: response_handler,delay: 10000});

A primeiro parâmetro é o endereço a ser chamado. O parâmetro response recebe uma função a ser chamada quando a resposta estiver disponível. O parâmetro delay define o tempo entre duas chamadas em milisegundos.

Ainda é possível passar os seguintes parâmetros:

  • um parâmetro error que recebe uma função para tratamento de erros de requisição,
  • um parâmetro request que pode ou receber uma string de parâmetros a serem enviados na requisição (no formato de URL) ou uma função que é chamada antes de cada requisição e que retorna a string de parâmetros (útil para requisições que podem variar ao longo do tempo)
  • um parametro method que define o método de envio (get ou post). O método default é get.

É real…

Pequeno comentário: alguns podem achar que a juice lib, devido ao fato de ter sido colocada no ar no dia 1 de abril, é uma brincadeira. Mas eu confirmo: É REAL !!!

Inclusive, acabei de colocar a versão 0.1.1, corrigindo pequenos bugs do IE.

Comentários, críticas e sugestões continuam sendo bem vindas.

Juice Lib

Acabo de disponibilizar no Google Code a JUICE Lib, uma biblioteca javascript para desenvolvimento de interfaces web baseadas em AJAX. Esta biblioteca é composta por vários pedaços de código que eu escrevi ao longo dos últimos 3 anos para meus projetos web, e que eu resolvi compilar e organizar.

A Juice oferece as seguintes funcionalidades:

  • funções para manipulação de texto, como StringBuffers e funções strip em Strings.
  • funções map, reduce e filter para manipulação de dados em arrays.
  • funções para manipulação de dados em dicionários, ou arrays associativos.
  • sisteminha simples de log.
  • funções de tratamento de eventos onload e de teclado.
  • e finalmente, funções para execução de chamadas RPC com XMLHttpRequest de forma simples e elegante.

E porque utilizar esta lib, se já existem milhares de outras ? Bem, eu diria que a resposta mais direta seria que a Juice Lib é leve, simples de se usar e fornece funções básicas para implementação de funcionalidades úteis em interfaces web. Aos poucos irei adicionar outras funcionalidades que implementei e que considero úteis.

O código pode ser visualizado e carregado em http://code.google.com/p/juicelib/. A documentação atualmente é inexistente, mas eu forneço junto com a lib um arquivo HTML com chamadas a todas as funções do sistema que funciona como um HowTo.

Dicas, sugestões e críticas serão bem vindas.

Next Page »