quinta-feira, 22 de setembro de 2011
Java decompiler para o Eclipse
Permite fazer o decompile da class enquanto fazemos debug, para determinar a fonte do problema.
terça-feira, 9 de agosto de 2011
IE8 Document Mode é Sticky !

Mais uma "feature" do IE8!
Se tivermos uma página simples, que abrimos em dois tabs, mas no primeiro tab definimos o URL como 'localhost' e o outro tab com o URL com o nome da máquina propriamente dito ("wheat", no exemplo).
Vamos constatar que o IE8, vai fazer o 'render' da página com margin e offset distintos, para a tag BODY.
A página está definida com o seguinte DOCTYPE:
<!-- DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" -->
Após mais alguns testes, acabei por descobrir que o problema não era do URL, mas sim devido ao facto de ter reutilizado um tab (alterando o seu URL), que conteve anteriormente uma página que forçou o modo de compatibilidade 'IE7' no IE8, com o seguinte meta dado no head !
<meta http-equiv="X-UA-Compatible" content="IE=8"/>
Resumindo e concluindo, o modo de compatibilidade aparentemente é uma propriedade do tab, e que não muda com a alteração do endereço (URL), como devia.
Isto implica que uma página que faça um render correcto, seguindo os standards, pode ficar completamente desfigurada no IE, se o tab tiver sido usado para aceder a outra página previamente, que tenha forçado o modo de compatibilidade do IE.
sexta-feira, 22 de julho de 2011
IE8 não gera evento form submit, em certas condições
Infelizmente os bugs são mais que muitos: James Hopkins IE8 Bugs e Gérald Talbot's IE8 Bugs chegam para ter uma ideia dos problemas que se tem pela frente, já para não falar nos modos de (in)compatibilidade, que o bicho trás para o IE7.
Estranho é que alguns anos após o lançamento do IE8, a grande maioria dos problemas continua por resolver.
Mas voltando ao que interessa, o IE8 tem outro BUG ainda não documentado que consiste na falha em gerar um evento de 'submit' num form, em certas condições.
Se tivermos o seguinte código, o IE8 gera o evento 'submit' correctamente:
<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input type="submit" value="Submit" />
</form>
Mas se quisermos adicionar um botão adicional, para por exemplo limpar o form (exemplo simplificado), o evento já não é despoletado.
NOTA: A implementação da funcionalidade em 'javascript' não é mostrada.
<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input id="iClear" type="button" value="limpar" />
<input id="iSubmit" type="submit" value="Submit" />
</form>
E isto acontece apenas e somente, porque o IE8 não gosta que exista nenhum INPUT do tipo 'button', antes de um INPUT do tipo 'submit'. Isto é. aparentemente o IE8 procura o primeiro botão disponível e activa-o, mas se não fôr um botão do tipo 'submit', o form não é submetido, pois activa o botão errado.
A solução passa por ter o INPUT com o type='submit' aparecer em primeiro lugar no HTML.
<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input id="iSubmit" type="submit" value="Submit" />
<input id="iClear" type="button" value="limpar" />
</form>
Se não gostarem do botão à esquerda, até por questões de usabilidade, podem sempre posicionar os botões por css com um float:right, que na pratica vos inverte a ordem relativamente a existente no HTML.
quarta-feira, 30 de setembro de 2009
Tabela com múltiplos THEAD versus TBODY (IE Quirk)
Caso se crie uma table com mais do que um thead, algo deste género:
<table id="myTable" cellspacing="0px">
<thead>
<tr>
<th colspan="7">Outubro</th>
</tr>
<tr>
<th>Domingo</th>
<th>2ª-Feira</th>
<th>3ª-Feira</th>
<th>4ª-Feira</th>
<th>5ª-Feira</th>
<th>6ª-Feira</th>
<th>Sábado</th>
</tr>
</thead>
<thead class="days">
<tr>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
</tr>
</thead>
<tbody>
<tr>
<td>TESTE</td>
...
</tr>
...
</tbody>
<tfoot>
...
</tfoot>
</table>
Tudo funciona perfeitamente (em FF3.0.14 ou no IE6.02900), inclusive aplicar CSS específico ao thead cuja class="days".
Mas se tentarem aceder por javascript ao array the objectos tBodies da tabela, as coisas ai mudam de figura.
var myTable = document.getElementById( 'myTable' );
var rows = myTable.tBodies[0].rows;
alert( 'Dados da primeira coluna do body = ' + rows[0].cells[0].innerHTML );
No caso do FF, retorna exactamente o esperado "TESTE", no entanto, no caso do IE vai retornar "4" ou seja, o conteúdo da primeira coluna do segundo thead.
Isto acontece porque o IE, erradamente associa o segundo thead (days), como se fosse o primeiro tbody, o que claramente não é, inclusivamente é incoerente com a aplicação de estilos, que essa sim funciona correctamente.
A solução para o problema, passa por fugir dele :) isto é, evitar o uso do thead adicional, e aplicar o estilo (class) directamente no tr. Não esquecer de actualizar o CSS de forma a corresponder com a alteração efectuada.
<table id="myTable" cellspacing="0px">
<thead>
<tr>
<th colspan="7">Outubro</th>
</tr>
<tr>
<th>Domingo</th>
<th>2ª-Feira</th>
<th>3ª-Feira</th>
<th>4ª-Feira</th>
<th>5ª-Feira</th>
<th>6ª-Feira</th>
<th>Sábado</th>
</tr>
<tr class="days">
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
</tr>
</thead>
...
</table>
quarta-feira, 19 de dezembro de 2007
JSPs e comentários
<%
...
SimpleDateFormat javascriptDateFormat = new SimpleDateFormat( "yyyy, (MM-1), dd" );
// usage: var mydate = new Date( <%= javascriptDateFormat.format( myJavaDate ) %> )
...
%>
À partida parece estar tudo bem, mas não está, porque o pre-processador das JSPs não gosta de tags embebidas (<% ... %>). Como executa/processa antes do compilador Java, e não considera os comentários java (// ou /* ... */) caput!
A solução passa então por comentar usando comentários JSP.
<%
...
SimpleDateFormat javascriptDateFormat = new SimpleDateFormat( "yyyy, (MM-1), dd" );
<%-- // usage: var mydate = new Date( <%= javascriptDateFormat.format( myJavaDate ) %> ) --%>
...
%>
Mas novamente, esbarramos com a limitação das tags embebidas não serem suportadas pelo Pre-processador JSP. Vamos resolver o problema fechando e abrindo o bloco envolvente de forma a evitar que um bloco fique contido no outro:
<%
...
SimpleDateFormat javascriptDateFormat = new SimpleDateFormat( "yyyy, (MM-1), dd" );
%> <%-- // usage: var mydate = new Date( <%= javascriptDateFormat.format( myJavaDate ) %> ) --%> <%
...
%>
E agora já funciona e até seria um resultado expectável, não fosse haver aqui algo estranho!
A formatação da data, que está em código JSP, está dentro de um comentário JSP, ora reparem bem:
<%-- // usage: var mydate = new Date( <%= javascriptDateFormat.format( myJavaDate ) %> ) --%>
Ou seja, tags para código JSP (<% ... %>) podem estar contidas em comentários JSP (<%-- ... --%>), mas o inverso não é verdade !
Confuso no mínimo.
segunda-feira, 17 de dezembro de 2007
CSS - IE6 versus Selector de Atributos
div.Field input[type="text"]
{
color: blue;
}
Assim, temos que circundar o problema, e a solução mais comum, é adicionar uma class específica para o caso que queremos resolver, e atribuir a class ao elemento respectivo, por exemplo:
div.Field input.Text /* IE6 Does NOT support attribute selector */
{
color: blue;
}
Passamos então a representar o conteudo da seguinte forma:
<div class="Field">
<label for="Name">Nome</label>:<input class="Text" type="text" id="Name" value="">
</div>
Mas numa perspectiva futura, podemos querer suportar ambas as regras, com algo como o seguinte:
div.Field input[type="text"],
div.Field input.Text /* IE6 Does NOT support attribute selector */
{
color: blue;
}
Perfeitamente válido ! Certo ?
Sim, é perfeitamente válido segundo o standard; Mas não, não funciona no IE6!
E de nada vale trocar a ordem das regras, dado que o comportamento é exactamente o mesmo.
O problema é devido ao IE6 rejeitar as regras que não suporta, conjuntamente com qualquer outra que lhe esteja associada.
Para resolver o problema temos que duplicar as formatações, de forma a que a rejeição da regra não suportada, não afecte as restantes, ou seja:
div.Field input[type="text"]
{
color: blue;
}
div.Field input.Text /* IE6 Does NOT support attribute selector */
{
color: blue;
}
Saber isto pode poupar-vos muito tempo :)
terça-feira, 13 de novembro de 2007
Validação de Parametros
boolean bDisabled = (new Boolean ((String) (request.getParameter("bDisabled")))).booleanValue();
É mais um caso de conversões implícitas, usadas abusivamente. Mas desta vez o programador, gostou de complicar a coisa, para além do razoável.Nomeadamente, é preciso que quem chame a página, saiba exactamente, qual é a conversão implícita esperada, que é "true" para true e "false" para false, e tem que respeitar o case.
Assumindo eu, que é válida a seguinte afirmação:
Se não é "true" é implicitamente "false".Então podemos optar por algo bem mais simples.
A vantagem é óbvia em termos de legibilidade e eficiência.boolean bDisabled = "true".equals( request.getParameter( "bDisabled" ) );
Nota: No caso em que o parâmetro não é enviado, assumimos que seja equivalente a false, o que é uma assumpção razoável, mas que validei no código existente como perfeitamente válida.
Caso não fosse, bastaria testar esse caso também, e gerar uma excepção para qualquer outro caso, por exemplo.