Skip navigation.

miscoded

the web is a hack

Posts tagged with "addEventListener"

Rabobank trusts only Rabokeys

, , ,

The Rabobank site in the Netherlands has a peculiar problem caused by an even weirder script. The forum discussion explains what the problem is: the site's search box doesn't allow you to type the letter T!

This is caused by a keypress handling JavaScript - it's all on one line so I made a re-formatted copy. If you thought the bug was weird, wait till you try figuring out what the point of the script is..

The basic logic that causes the problem is: "any browser that supports addEventListener() will support charCode but not keyCode in the keypress event". As it happens, Opera does support addEventListener() but not charCode. The site blocks keypress events with keyCode 116 which is the correct keyCode for a "t" keypress. (If we didn't support addEventListener they would listen for keyDown events with keyCode 116 instead - which is what they basically intended to do.)

With the problem analysis out of the way: I simply don't get what this site is trying to do. They set one handler for keypress events to cancel them if it's the F5 key, and another handler for keyup events to call location.reload() if it's the F5 key!? See here:

function F5DownEventHandler(evt){
this.target=evt.target||evt.srcElement;
this.keyCode=evt.keyCode||evt.which;
this.altKey=evt.altKey;
this.ctrlKey=evt.ctrlKey;
var targtype=this.target.type;
if(this.keyCode==116&&(evt.charCode==null||evt.charCode==0)){
return cancelKey(evt,this.keyCode,this.target)
}
if(this.keyCode==13&&(this.target.id=='z01'||this.target.id=='z02'||this.target.name=='z5'||this.target.id=='ra_searchfield2'||this.target.name=='z81')){
return cancelKey(evt,this.keyCode,this.target)
}
}
function F5UpEventHandler(evt){
this.target=evt.target||evt.srcElement;
this.keyCode=evt.keyCode||evt.which;
this.altKey=evt.altKey;
this.ctrlKey=evt.ctrlKey;
var targtype=this.target.type;
if(this.keyCode==116&&(evt.charCode==null||evt.charCode==0)){
window.location.reload(this.ctrlKey)
}
if(this.keyCode==13&&(this.target.id=='z01'||this.target.id=='z02'||this.target.name=='z5'||this.target.id=='ra_searchfield2'||this.target.name=='z81')){
this.target.parentNode.parentNode.submit()
}
}


So: "we don't mind that [F5] reloads the page and [enter] submits forms as long as we re-implement the browser's functionality in JavaScript".

Or: Rabobank trusts only Rabo-programmed keys?

I guess the browser's OWN implementation of [F5] and [enter] just wasn't buggy enough. :wink:

captured in India

, , ,

Google Indic Transliteration does quite precisely nothing in Opera. The reason is that they try adding a capturing key event listener to a TEXTAREA:

a.addEventListener(b,c,true)

from function _TR_addHandler in labs001.js.

If you've followed the past twists of the event capture drama, you might recall that since Mozilla decided to play chicken and re-write the spec according to their buggy implementation, we decided to be bug compatible. So why is the transliteration still broken? Seems like we aren't quite compatible after all?
Yup. Test case here.
Capturing key event listeners still don't fire on target. That's a bug in our bug compatibility, leaving us more standards compliant than intended.

So our bugs are buggy :whistle: . How do you spell "irony" in Hindi again?

Firefox's pageshow and pagehide events not DOM2 events-compatible?

, , , ...

These events sound quite interesting and author friendly. But unless I'm missing something their current implementation in Firefox simply sucks!

I tried
document.addEventListener( 'pageShow', function(e){ log('pageshow fired'); }, false );
document.addEventListener( 'pageHide', function(e){ log('pagehide fired'); }, false );


No go. Then I tried window.addEventListener but that doesn't work either. Finally, I looked at the sample code and noticed it only shows DOM0-style event handlers -
<body onPageShow="..."
. :yuck: Really?? That makes the events pretty useless. I would like Opera to support similar events but Firefox's implementation looks too broken to copy. Tell me I'm missing something..

Firechicken

, , ,

Over at Mozilla.org they've been working on fixing their load events capture bug. That's great news, because Opera has had lots of trouble with sites that used event capture when they didn't intend to do so. We had the correct, spec-compliant implementation. However, web developers don't read specs. They test in browsers. We suffered the incompatibility problems because sites were written for Firefox's implementation. We've had ugly problems caused by this issue for years, on extremely important sites like AOL.com, and we've worked hard through Open The Web, information and even site patching.

Inevitably, when Firefox fixes the bug they run into those badly coded sites. They start seeing the problems we've had all along. So what do they do? They play chicken! They decide to tweak the spec to solve the problem their bugs created in the first place.

If they go for this solution, we have to follow them for compliance.

To be fair, I do think that aligning a spec to the web can be a good solution, as long as it ensures interoperability and covers the use cases. And the DOM2 Events spec itself is vague. I guess the problem is a spec that attempts to be so language-generic that it avoids referring to even the all-important JavaScript window object, it isn't clearly specified where the window object fits into the event capture/bubble model. They can and probably will argue that their implementation is DOM conformant (and make sure the HTML5/web apps spec lands on their side?).

I'm still disappointed.

event capture explained

, , , ...

What is event capture, and what are the implementation gotchas that cause problems for browsers and webmasters? Read on for details..

Read more...

Google maps and event transparency

, , , ...

If you use Google Maps with Opera 9 betas you have probably noticed that the top left navigation does virtually nothing. Only the slider works at the moment.

Technically, they use an empty element that is styled to cover the graphic to catch mouse events and call the navigation actions. (Don't ask me why it is coded like that, and why for example the graphic isn't the background of the DIV so that this problem doesn't arise).

This not working in Opera is caused by our experimental support for event transparency.

At first sight I thought I had missed something in IE's implementation that would make Google Maps work. However, none of my tests could identify the missing piece of that puzzle - and it turns out what they actually do is to set a background colour on the empty element and then make it invisible again by setting an opacity filter!

Now, there is no natural link between event transparency and opacity. If a UA implements the former but not the latter, our Google Mappers would have to look for another workaround. It is pure luck that Opera happens to add support for both at the same time, so Google will fix this by using the IE workaround for Opera too.

This issue shows how important it is to standardise a way to say an event should fire on invisible elements. I think addEventListener should be extended with a fourth argument that controls this.

As an aside, to avoid browser sniffing you can use this code to detect support for CSS3 opacity in UAs that support the DOM standard's getComputedStyle:

var el=document.createElement('div');
el.style.opacity='.5';
var opacitySupported=(getComputedStyle( el, 'opacity').opacity)?true:false;

Standards compliance victim

, , , ...

Coming soon to a screen near you!

New software drama, Standards compliance victim, starring:


Question of the day is: why does the "news slideshow" on AOL's front page run ten times too fast in Opera?

Because FireFox's implementation of DOM2Events has serious shortcomings, as I've mentioned earlier. AOL.com is the latest and most high-profile site that has run into this problem so far.

On AOL's main page the small "slideshow" runs much faster than it is supposed to, the "play/pause/next" buttons do not work, you get strange alerts about content not being available, and the whole page makes Opera use a lot of CPU resources. This is all because they use a capturing "load" event listener when they meant to use a non-capturing one.

It works in FireFox because it does not support capturing event listeners. It fails in Opera because we follow the spec.

I've written a couple of pages to show the difference. Try these in FireFox and Opera:



Since I have written the test cases, could someone do me a favour and make sure there is a Bugzilla report on the second issue? I know bug 235441 covers the former.

IE's event transparency logic

, , , ...

In IE you can sometimes click "through" an element and activate something that is underneath. We've been pondering for a while what the exact behaviour is (and so have the Mozilla devs).

After several test files and experiments, I think I've nailed it - here are IE's event transparency rules. If I have missed anything or you notice a scenario that isn't according to these rules please let me know.

General rules

IE considers an area of an element "transparent" if

a) the computed style of the "background-color" is "transparent"
AND
b) the computed style of "background-image" is "none"
AND
c) it is outside the inline boxes generated by element contents (not counting line-height)
AND
d) it is outside the element's borders (including invisible table borders)

OR

e) it is outside a CSS clip rectangle

OR

f) if "visibility" is "hidden"

Event processing

When a mouse event occurs above a transparent area of the initial target, IE checks the elements in stacking order.

While the current event target area is transparent according to the rules above and is not BODY, IE examines the element below.

If current event target is BODY the topmost element gets the event.

If current event target area is not transparent it will get the event if the event is within a content box or on a border. Otherwise, the event goes to the initial target.



Special cases that are transparent to events:

PNG with alpha channel and the AlphaImageLoader filter applied - the fully transparent areas

IFRAME with attribute allowtransparency and contents with style background: transparent applied

Transparent parts of OBJECT with wmode=transparent

Notes

Clipping does make the clipped region transparent even if the element has backgrounds/background images

Opacity filters and background-position/repeat have no effect on transparency for event handling purposes.

If the event does not reach the BODY element because the target point is positioned outside the BODY, it will go to the bottom-most element, normally HTML.

Line-height does not affect transparency - the extra space inbetween the lines is transparent to events

Table elements are never transparent to events