miscoded

the web is a hack

Subscribe to RSS feed

Posts tagged with "PAS"

either too old or too modern (!)

, , ,

A few things about this source code might be amusing, but the funniest thing is that the developer writing it was clear-sighted enough to predict that a web browser "too modern" to deal with his code might one day emerge:
//PopUp Calendar BEGIN--------------
if (navigator.appName != "Netscape")
{
if (document.all) {
	document.writeln("<div id=\"PopUpCalendar\" style=\"position:absolute; left:0px; top:0px; z-index:7; width:200px; height:77px; overflow: visible; visibility: hidden; background-color: #FFFFFF; border: 1px none #000000\" onMouseOver=\"if(ppcTI){clearTimeout(ppcTI);ppcTI=false;}\" onMouseOut=\"ppcTI=setTimeout(\'hideCalendar()\',500)\">");
	document.writeln("<div id=\"monthSelector\" style=\"position:absolute; left:0px; top:0px; z-index:9; width:181px; height:27px; overflow: visible; visibility:inherit\">");}
else if (document.layers) {
	document.writeln("<layer id=\"PopUpCalendar\" pagex=\"0\" pagey=\"0\" width=\"200\" height=\"200\" z-index=\"100\" visibility=\"hide\" bgcolor=\"#FFFFFF\" onMouseOver=\"if(ppcTI){clearTimeout(ppcTI);ppcTI=false;}\" onMouseOut=\"ppcTI=setTimeout('hideCalendar()',500)\">");
	document.writeln("<layer id=\"monthSelector\" left=\"0\" top=\"0\" width=\"181\" height=\"27\" z-index=\"9\" visibility=\"inherit\">");}
else {
	document.writeln("<p><font color=\"#FF0000\"><b>Error ! The current browser is either too old or too modern (usind DOM document structure).</b></font></p>");}
}
	document.write ("<noscript><p><font color=\"#FF0000\"><b>JavaScript is not activated !</b></font></p></noscript>");
The result is the red warning message on this page of an airline I must be too modern to book tickets from: So, actually, simply by switching navigator.appName from "Netscape" to "Opera" a few years back we became modern. So that's a challenge to Chrome, Firefox and IE: you know you want to be as modern as us - what are you waiting for? smile

Are you neither Firefox nor Internet Explorer?? You must be..

, , ,

function hide(arg2){
	if(browserType=="gecko"){
		document.poppedLayer=eval("document.getElementById(arg2)");
	}
	else{
		if(browserType=="ie"){
			document.poppedLayer=eval("document.all[arg2]");
		}
		else{
			document.poppedLayer=eval("document.layers[arg2]");
		}
	}
	document.poppedLayer.style.display="none";
}

cry
These quaint remnants from a time where a giant, binary, document.layer-supporting lizard named Netscape 4 roamed the World Wide Web were found on Virgin America's site.

Virgin America, would you please (belatedly) enter the 21st century?

Why Twitter doesn't count

, , , ...

If you're a Twitter user, you might be wondering why Twitter suddenly stopped updating the character count when you write a new tweet in Opera.

Why? Well, this is how they decide what events to listen to in order to update the counter:

if($.browser.mozilla){
  A.push("input","keydown","keyup")
}else{
  if($.browser.webkit){
    A.push("textInput","keydown","keyup")
  }
}


A stunning display of entirely pointless browser sniffing, given that registering a listener for an event the browser does not support is a harmless no-op. Dear Twitter, I'm ashamed of you.

Aside, here is some fascinating reverse engineering of the Trending Topics algorithm, demonstrating that Twitter pretty much fails to give us a real picture of what is being most discussed on the site: How Twitter kept Wikileaks from trending, and why.

So that's the way mass media 2.0 go tabloid - through algorithms that favour trivia over substance.

Tracking down finnair.com's missing i

, , ,

I guess Finnair is the household's favourite airline. I don't think I've used any other carrier during the last three years or so - we don't travel that much, so we're not talking many flights overall. However, it was rather annoying to find its website broken last time I wanted to look up some prices:

Finnair site auto-complete menu broken, error in console

After selecting a local site, the auto-complete menu to choose departure and destination cities from never populates. What's worse: the site doesn't accept anything you type in by hand! If you haven't made a menu selection, you get an error message! I'm sure that does wonders for their overall accessibility and section 508 compliance..

The error message complains that they refer to a variable "i" that doesn't exist. Somewhat wrapped, the code looks like this:

a.Autocompleter.Cache=function(c){
	var f={};
	var d=0;
	function h(k,j){
		if(!c.matchCase){
			k=k.toLowerCase();
		}
		if(!k.startsWith(j)&&k.indexOf(" "+j)===-1&&k.indexOf("("+j)===-1){
			return false;
		}
		return i==0||c.matchContains;
	}

The problem is the reference to i in the return statement. There is no variable "i" defined nearby, indeed not in the entire script file. That "i==0" looks like some dead code that isn't meant to be there anymore. But it works in other browsers, no?

If I load the page in Firefox and type javascript:alert(window.i) into the address bar it says "1", so in Firefox the site does somewhere create a global variable named i. The question is where?

Firebug can't - as far as I know - break when a variable is initialized or changed. As always, Fiddler comes to the rescue - setting a "HTTP breakpoint" after response and re-loading the site in Firefox lets me add some simple debug code:
Fiddler screen in breakpoint mode, debug code highlighted
window.__defineSetter__ ('i', function(){ try{ undefined() ; }catch(e){ console.log(e) ; } })

When I click Fiddler's "run to completion" button, an error message appears in Firebug's console pointing to this function:

function isFirefoxWMPPluginInstalled(){
	var plugs=navigator.plugins;
	for(i=0;
	i<plugs.length;
	i++){

which given its name is naturally called after some browser sniffing, here:
type:$.browser.mozilla&&isFirefoxWMPPluginInstalled()?"application/x-ms-wmp":"application/x-mplayer2"


So this works in other browsers by pure luck - because JavaScript scoping rules are such that when you don't use "var" keyword to declare variables, they will be global, and Fnnar's code contains numerous loops that use "i" as a counter and don't use var. If such a loop happens to run before you try booking, the site will work for you. As if we needed any more evidence that JavaScript scoping rules suck..

If we're going to site patch this error in browser.js, the patch would be simply var i;. At 6 characters, I'm fairly sure it would be the shortest site patch ever. Meanwhile, we'll contact them and hope Fnnar will get their "i"s back in order.

And I sure hope they deploy better software for their autopilot than their autocomplete...

Onestat.com's browser sniffer older than my son

, , ,

Seems the boss has been browsing web stats again - I came across a bug report from him saying a DHTML menu on onestat.com only works once. (Load page, click any "demo" link at the bottom and try the menu on the left.)

I'm not paying that much attention to stats myself, being too busy doing the work that will hopefully smoothen out compatibility problems and make it possible to grow our usage share. It's exactly the type of brokenness Jon found on onestat.com I fear the most - a bit hidden away, subtle, annoying when the user needs that page to work but perhaps not disastrous enough to notify us of. Too many of these issues, and we've lost a user! (Unless, of course, the user happens to be our CEO smile - luckily he's an active surfer who comes across more compat problems than any average user and eagerly reports them wink).

Now, deep inside the Onestat scripts is some code to handle browser differences. The script assumes that a browser below a certain level of DOM support can't be expected to create menus after the document loaded. That's of course not a bad assumption to make - until you see the sniffing they use to determine whether you have sufficient DOM support. Here is the relevant part:
if(kh.indexOf("Opera/7")>-1||kh.indexOf("Opera 7")>-1)return "Op7"; 
. 
. 
else if(kh.indexOf("Opera")>-1)return "Default";


Check the calendar, sir: we're in late 2009. Opera 7 - the only Opera version this script thinks is capable of opening the menu a second time - was released in January 2003. That's a 6 year old browser sniffer! I hope the script that generates their statistics is a bit more up to date!

And it's more than a little ironic that a web statistics company contributes to Opera's low usage share by running such old and broken code on their website. sad

Most expensive javascript ever?

, , ,

I've wanted to tell this story for a while, and I don't think I'm spilling any beans or disclosing any sensitive information at this point.

So, a while ago Opera Software needed more servers. Not just a few servers either - we were planning Opera Mini's growth, implementing Opera Link, and My Opera was also growing quickly. We predicted crazy server load increases for the foreseeable future (and man, were we right!)

Clearly we needed to make a massive investment on the server capacity front (basically buying these shiny things and then some.)

Management put a hefty check on the table - I'm sure our beloved sysadmins felt like kids before Christmas - and salivating sales people from major hardware vendors grabbed our requirements spec, dived into their CRMs and crunched their spreadsheets. They emerged with offers and sample servers shipped all the way to Oslo for our testing pleasure.

However, one of the world's biggest hardware vendors - whose name every single reader will be familiar with, and whose hardware a good share of you will be using right now - apparently didn't do their homework. When Opera's sysadmin booted up the server to test its web-based administration interface, they came across a single JavaScript statement that managed to piss off everyone up to and including the CTO.

This single statement, apparently written by some sub-contractor they had outsourced admin interface programming to, cost them millions of NOK in lost sales.

And the code they sent all the way to Oslo for testing? Here's an extract:

if (is.opera)
{
window.location.href="config/error.htm";
}

'ESPN FLASH detection system' meets Flash 0

, , , ...

Even in the classy company of bad version detection scripts we've met since we started testing Opera 10, this Flash detection approach stands out. That script goes to great effort to require an update every.single.time Adobe releases another Flash version.

It starts with a bold claim to be the ESPN "Flash detection system", no less:

// Author: Danny Mavromatis
// Version: 2.07.0
// Created: 10/29/2001
// Updated: 3/6/2006
// ESPN.com FLASH detection system
	var f2 = false;
	var f3 = false;
	var f4 = false;
	var f5 = false;
	var f6 = false;
	var f7 = false;
	var f8 = false;
	var f9 = false;

Look at all those variables. What might they be used for? Read on:

var fD = navigator.plugins["Shockwave Flash" + isVersion2].description;
var fV = parseInt(fD.charAt(fD.indexOf(".") - 1));

So, first it extracts one single letter that precedes a dot in the plugin's description of itself. This is presumably the plugin's major version number, you know the 8 in "8.0", the 9 in "9.0", and, um, the 0 in "10.0". Then:
f2 = fV == 2;
f3 = fV == 3;
f4 = fV == 4;
f5 = fV == 5;
f6 = fV == 6;
f7 = fV == 7;
f8 = fV == 8;
f9 = fV == 9;


..it just sets the corresponding "f"-variable to true. If the major version was 8, f8 will be true and so on. A great way to make sure the code will require maintenance - new variables for each new version. And then comes the real gem:

for (var i = 2; i <= mV; i++) {
if (eval("f" + i) == true) aV = i;
}
// alert("version detected: " + aV);

[/code]

Let's see, we just had a variable fV which contained Flash's major version number (or at least its least significant digit) - but this script has severe amnesia. What was that number again? Better use a loop and 8 eval() calls to check the value of that variable. You never know, do you?

Now, dear readers - Mr. Mavromatis clearly needs some help with this code. Obviously, complexity and maintenance requirements are among his design goals. The natural question is whether there are good, non-obvious ways this script could be improved to be more complex and require even more maintenance? Suggestions welcome in comments.

Update: Danny Mavromatis responded in comments and - though he no longer works on the ESPN site - has made sure that the page where we found this problem has been updated. Kudos to Mr. Mavromatis for his quick response and sense of responsibility. I wish more web developers would act this way!

No more personal attacks, please!

X-Talisman-Compatible: messup

, , ,

Yikes.

I'm seeing X-UA-Compatible abuse everywhere these days. It seems most of the big sites I look at have decided not to give the IE8 team half a chance to iron out their bugs, they've all simply decided to close their eyes and slap on a "behave like IE7" instruction instead. Guess if this is going to cause compat problems down the road when all non-IE browsers are forced to look at the META tags and figure out if they should be bug-compatible with IE7, 8 or 9 for any given site.. :-(

Here's a funny offender: adobe.com insists that if I'm going to show their "flashAbout_info_small.swf" animation correctly, then ..

GET /swf/software/flash/about/flashAbout_info_small.swf HTTP/1.0
Host: www.adobe.com
Referer: http://www.adobe.com/products/flash/about/

HTTP/1.1 200 OK
X-UA-Compatible: IE=7
Content-Type: application/x-shockwave-flash

Date: Sat, 21 Feb 2009 23:39:33 GMT
Content-Length: 594

... I have to render the .swf like IE7 would.

No problems, Adobe. Since I work for a browser vendor the server's wish should be my command. Here's your about Flash SWF rendered by IE in IE7 compat mode:



Beautifully compatible, no? Thanks for the X-UA-Compatible hint, I would never have figured that out on my own!