Skip navigation.

exploreopera

| Help

Sign up | Help

Posts tagged with "quirks"

being compatible with the dark matter of the web

, , , ...

A forum thread asks the oft rehearsed question "why can't Opera be more compatible with websites". Allow me to respond with a blog post since that discussion is somewhat noisy already..

Simply: Opera 9 already supports the W3C and ECMA standards that are widely used, it also supports lots of non-standard and pre-standard features to the extent that these are documented by others or by our own testing. Compatibility today is in the details. A big, generic question like "what technologies should Opera support to be more compatible" won't get you far. If a problem isn't caused by sniffing or similar broken code, the likely culprit is a minor detail being different across browsers, not having to support another "technology". Hence, discussing compatibility needs to dive into the technical details and avoid sweeping generalisations - and I hope to provide some examples that are specific enough to perhaps bring the discussion forward:

event.button

Careful and correct implementation of standards goes a long way, unless standards differ from reality. Values of event.button is a damned-if-you-do, damned-if-you-dont scenario: IE and the DOM standard numbers mouse buttons differently, and there is lots of content depending on either of these. Depending on how the site detects "IE" custom scroll bars, mouse-drags and other fancy mouse usage stops working. Options?
  • Break this half of the web
  • Break the other half of the web
  • Cry and tear your hair out

Bohoo.

XMLDocument object
This is an interesting Firefox thingy. It's not in any standard, Firefox just happens to make it available to scripts because internal Firefox architecture has an "XMLDocument" class. While this probably makes sense for Firefox's architecture it doesn't make sense for Opera's. We didn't really notice the XMLDocument object until we investigated why Sarissa doesn't work 100% in Opera. Yahoo Mail Beta uses it too. Options?
  • Complain to Mozilla because cross-browser compatibility suffers from their exposed internals?
  • Spend time tracking how it works and implement it as yet-another-nonstandard-we-must-support?
  • Bug Mozilla to have it standardised so that we can implement it?
  • Nag websites about not using it, or detecting it correctly?


XUL
Some stuff mentioned in the forum thread uses XUL. Yes, this is a reasonably open, non-standard technology invented by Mozilla which Opera has chosen not to support. The main reason we don't is very pragmatic: there hasn't been that much demand for it. Lack of this technology is very unlikely to be the reason why your Opera-newbie friends complain about sites not working in Opera. Options?
  • Support
  • Not support
  • Wait for standardisation, then support.
  • Wait for actual usage growing on the web, then support


Windows MediaPlayer scripting
Now this is truly a skeleton in the compatibility closet. WMP's latest scripting support only works with the ActiveX control. Since Opera doesn't support ActiveX we're stuck with an outdated version of WMP's scripting engine, and quite a lot of fancy video player user interfaces on the web are not written to fall back to use the older version if ActiveX isn't available. Did you say "standard"? Bah, there is no such thing in the world of plugin vendors - vendor lock-in is the name of the game here. WMP, Real, QuickTime, Flash - the scripting interfaces are all different, and once a developer has learnt one and a company has invested in building a website on one the cost of switching is naturally high. Options?
  • Support ActiveX?
  • Fake ActiveX?
  • Add some other kind of compatibility layer?
  • Continue the endless quest of web openers?


Dark matter

They say most of the universe consists of dark matter. Many, many compatibility problems are caused by the dark matter known as convention. All the stuff that we have to do simply because other browsers do. If a site forgets to add a closing SPAN tag, the parser constructing the DOM is going to have to try to compensate. When it turns out that IE's innerHTML in such a case apparently is inconsistent with the DOM it has built, kaboom - pictures.aol.com is broken in Opera. Hit by the dark matter..

Some things can't and won't be standardised (who would have thought that simply taking less than one second opening a popup window breaks a page??) but one of the greatest frontiers of web compatibility work is to expand the standards to cover much more of the "dark matter". WHATWG rises to the challenge and W3C seems to be getting the message that the dark matter of convention is one of the most serious threats to cross-browser compatibility.

Dell goes for the quirks

, , , ...

This page should have a Flash in it. Now Opera, where is it?

Well, here's a pretty little function from Dell, meant to return an element with a specific name:

function ParseDivObjects( targetName )
{
var objs = document.getElementsByName( targetName );

//-- Workaround for "inconsistent" W3C ruleset in IE as DIV's aren't mapped with name properties
if( objs.length == 0 )
{
var targets = document.getElementsByTagName( "DIV" );
var tmpObj;

objs = new Array();

for( var targetidx = 0; targetidx < targets.length; targetidx++ )
{
tmpObj = targets[targetidx];
if( tmpObj.name == targetName )
{
objs.push( tmpObj );
}
}
}
return objs;
}


Let's start: document.getElementsByName is not supposed to be used for elements that are not supposed to have a "name" attribute. So, for example you can use getElementsByName with INPUT elements but not with DIV. Except that Mozilla apparently disagrees with that interpretation of the specification and thinks IE's behaviour is "a quirk". Really?

Anyway, Dell has a workaround for IE: they go through all DIVs in the page and check tmpObj.name, which means Opera is out of luck again. Since DIVs are not meant to have a "name" attribute we don't create any .name property for it. Using getAttribute here would make it work.

So Dell crams two different quirks into one function, and Opera fails because it supports neither. Time to violate the DOM spec a little more.. :frown:

IE's scrollHeight logic

, , , ...

Element dimension properties is such an unstandardised mess. Do not ask me to be your guide through this maze, but below is at least some documentation of how scrollHeight behaves in IE.

If element does not have "height" specified, scrollHeight returns height of element contents + padding + border (in other words exactly what offsetHeight does).

If height is specified scrollHeight returns height of element contents + padding only.


As for Opera, we seem to have some bugs. The problem with getting it right is that the scrollHeight beast is not in any standard, so we just have to try to do "what IE does" and discover through users reporting problems out there that we actually missed out half of the logic and ended up doing something entirely different and incompatible.

This is why standards are good for you.

What Opera does: scrollHeight returns border-top-width + padding-top + height of element contents (!). How did we get there? Including only half of the border and padding width - top but not bottom values?? I don't have a clue.

var arguments; in function body ignored in IE and FireFox

, , ,

(Warning: this post documents a very obscure and technical quirk. I won't even try to explain it in popular terms. ECMAScript geeks only. :smile: )

Opera can not enter the KLM website. The reason is a peculiar ECMAScript interpretation corner case quirk.

The issue is code like the excerpt below:

function (){
  var arguments;
  arguments['foo']='bar';
}


Now, Opera allows overwriting the function's arguments property with a local variable set to undefined. For some reason, FF and IE both ignore the "var arguments;" statement. This makes Opera throw an exception because "arguments" is the value undefined when you reach the line where you add properties, the others luckily escape this error and the site works for them.

Who is right? Most likely Opera. According to the ECMAScript spec you can overwrite the "arguments" array inside a function. It works cross-browser to say "var arguments=foo;", it is just overwriting it with nothing that seems to be incorrectly implemented in FireFox and IE.

I guess we may have to follow them and be bug-compatible.

For KLM the simple fix would be to say
var arguments={};

instead, because that's what they actually meant.

a sudden misstep while dancing with blogger

, , , ...

Imagine this: the browser and the website are like an ice skating couple. When they follow the choreography and are used to working together, the effect can be dazzling and we feel like we can watch or surf forever.

However, like any dancing couple knows: if you have performed together for a long time, you have grown accustomed to each other's peculiarities: weight, height, rhythms, accents, quirks. No new partner will ever be exactly the same, though they may be even better dancers on a simple technical level.

If you start dancing with a new partner, both may know the choreography perfectly but you'll never be prepared for how your partner was used to interact with the previous dancer. You will only discover through actually dancing together. An unexpected transfer of weight, and your skating partner hits the ice... That's why there are rehearsals.

A website needs to "partner" lots of different browsers. And browsers mostly discover through real-life site usage what odd quirks and habits the site has added to work around issues with the browsers is is used to working with. Like in dance, the oddities and habits are often the hardest things for a newcomer to adapt to.

Opera-users just hit a serious problem with blogger.com: the text of your post would disappear when submitted! It turned out to be one of these issues, an unexpected workaround against a problem with another browser hit a very obscure bug in Opera.

We fixed the bug for Opera 9, and the good people at Blogger kindly added a workaround for Opera to their JavaScript (you can now post again!).

Perhaps one day a new browser will come along and that particular code will be a stumbling block - a peculiar accent in the dance that made the choreography flow with that specific partner... That is the rhythm of site and browser development.

Superiour popup blocker fails popup "test"

, , ,

Popup blocking has been a bit of an arms race. Browsers have added more and more advanced heuristics to distinguish "wanted" and "unwanted" popups, and popup script authors have worked hard to find useful exceptions to the browser rules.

Most of the holes popup users have found in the previous popup blocking approaches have been fixed in the most recent browser versions. Opera's popup blocking has been vulnerable to Flash-trickery but that will be history in Opera 9.

However, some users have been curious why the page http://www.popupcheck.com/freescan/popup/popup_test_standard.asp appears to show several popups that evade the blocker. Analysing this issue throws light on some interesting quirks and browser differences.

There is one immediately obvious aspect of a good popup blocker: it should be good at separating "wanted" popups from "unwanted". Opera fails this popup test because you did ask for the popups - you clicked a link to start the test. In other words, Opera is better at detecting what popups you do want than whatever browser this test was tested with.

Another and more technical aspect is whether the script should be able to detect that the popup it tried to open was blocked. Opera goes further to avoid "popup blocker detection" than the others do: we return a dummy window object to the script. A popup blocking return object demo shows that most other popup blockers simply return null. Hence, even if this test started as an "unwanted" action it would be unable to detect that the popups were blocked.

The test simply makes too many assumptions about the popup blocker(s) it will be tested against.

intervals and timeouts quirks

,

Today I came across an oddity I wasn't aware of or had forgotten. It is the sort of quirk that makes you remember what a messy language JavaScript is: you can use clearInterval() to stop a timeout!

JavaScript has four methods for controlling timer events: setInterval(), setTimeout(), clearInterval(), clearTimeout(). They are pretty self-explanatory and simple to use: var someTimeout = setTimeout(myFunction, 500); // I want something to happen in half a second
clearTimeout(someTimeout); // oops, changed my mind. don't want that anyway
The interval functions work the same way. The only gotcha is that calling setTimeout or setInterval more than once assigning to the same variable will create multiple timeouts because the variable only stores a reference and isn't the timeout itself: var someTimeout = setTimeout(myFunction, 500); // Setting intial timeout
someTimeout = setTimeout(myFunction, 500); // overwriting variable means we can no longer cancel first timeout
clearTimeout(someTimeout); // so this only cancels the second one
It all makes sense, no? Until you meet the following script: var someTimeout = setTimeout(myFunction, 500); clearInterval(someTimeout); All the major browsers support this: clearInterval can stop a timeout. Not so tidy after all, then..

"Tested only in FireFox" signature error

, , ,

I've seen a particular mistake several times recently. It is a subtle ECMAScript spec violation that uncovers what browser engine was used during script development and testing: only Gecko-based browsers such as FireFox and presumably Mozilla allow it.

The error is to add a final comma inside an ECMAScript object literal:

var myObject = { property:'value' , }

Last seen in here and in an ad-hoc Chinese IME JavaScript demo (!) which I can't re-locate at the moment.

Try it out with the following bookmarklet:

javascript:try{eval("var a={a:'a',};");alert('Wrong behaviour!')}catch(e){alert('Correct behaviour!')}

A first-class example of how a minor browser sloppiness creates a serious compatibility problem.