Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #5786 (closed enhancement: fixed)

Opened 2 years ago

Last modified 1 year ago

[PATCH] Event enhancements - IE scope correction and event object normalization

Reported by: Andrew Dupont <rubyonrails@andrewdupont.net> Assigned to: sam
Priority: high Milestone: 1.2.4
Component: Prototype Version: edge
Severity: major Keywords: 1.6 fixedinbranch
Cc: mislav, savetheclocktower, handcoding

Description

This patch is intended to reduce reliance on the Event.* methods. It patches Event.observe so that in IE, by default, "this" references in an event handler point to the object on which the handler was assigned, instead of the "window" object. (Note that you can still re-adjust this scope through "bindAsEventListener.")

It also aims to normalize the event parameter passed to the handler by creating the DOM event model equivalents of IE's event model properties. For instance, "e.target" grabs its value from "e.srcElement," "e.which" from "e.button," etc.. The stopPropagation and preventDefault methods are copied over too. (There's probably more that can be normalized; I'll check QuirksMode to be sure.)

The Event code has been modified as little as possible. It doesn't break compatibility with any existing scripts.

Attachments

event.patch.txt (2.5 kB) - added by Andrew Dupont <rubyonrails@andrewdupont.net> on 08/17/06 04:49:47.
event.diff (4.2 kB) - added by mislav on 11/26/06 10:23:40.
more elegant
event.2.diff (8.3 kB) - added by mislav on 11/29/06 08:48:03.
updated & polished with more love
event.html (9.5 kB) - added by mislav on 11/29/06 08:54:08.

Change History

08/17/06 04:49:47 changed by Andrew Dupont <rubyonrails@andrewdupont.net>

  • attachment event.patch.txt added.

09/03/06 20:35:02 changed by madrobby

  • status changed from new to closed.
  • resolution set to untested.

11/26/06 10:22:50 changed by mislav

  • status changed from closed to reopened.
  • resolution deleted.

Funny this being closed - Event module doesn't have tests in the first place.

Andrew, this is a sweet idea - but the patch is kind of clumsy. It really doesn't need element.handlers, Event._IEFixes, Function.prototype._fixScope. This is bloat to the framework.

11/26/06 10:23:40 changed by mislav

  • attachment event.diff added.

more elegant

(follow-up: ↓ 5 ) 11/26/06 10:36:41 changed by mislav

  • priority changed from normal to high.
  • summary changed from [PATCH] Event enhancements -- automatic scope correction and event object normalization to [PATCH] Event enhancements - IE scope correction and event object normalization.
  • severity changed from normal to major.
  • version set to edge.
  • milestone set to 1.2.

OK I've added my patch based on Andrew's great work.

  • automatic scope correction! try the test for it in IE
  • normalizes the event object in IE, bringing it closer to W3C DOM
  • Event.observe can now take an array as a first parameter

Try it, play with it. Ideas how to make unit tests or improve functional ones welcome :)

11/26/06 10:37:32 changed by mislav

  • cc set to mislav.

(in reply to: ↑ 3 ; follow-up: ↓ 6 ) 11/26/06 18:12:23 changed by savetheclocktower

Replying to mislav: I like it. Sorry about that first patch -- I was, umm, drunk. Yeah, that's it.

(in reply to: ↑ 5 ; follow-up: ↓ 7 ) 11/26/06 19:57:14 changed by mislav

Replying to savetheclocktower:

I like it.

Thanks. It can even be further improved, but I'm worrying about reducing performance if I did some of the stuff I thought about.

And, BTW, read "but it in [dir]..." as "put it in [dir]..." :) I don't even know if I should call them functional tests, but they are certainly useful. I'll investigate if events can be simulated (programatically triggered) in a cross-browser manner.

(in reply to: ↑ 6 ) 11/27/06 09:45:01 changed by madrobby

Replying to mislav:

And, BTW, read "but it in [dir]..." as "put it in [dir]..." :) I don't even know if I should call them functional tests, but they are certainly useful. I'll investigate if events can be simulated (programatically triggered) in a cross-browser manner.

Afaik, no. But we can do mock object for this, simulating what the "ideal" browser would call, and even simulating if we're on IE, Safari, Firefox or whatever. That's something we could need for other cross-browser stuff, too.

11/27/06 12:36:21 changed by mislav

  • keywords changed from event ie to event ie scope.

I've updated the patch and tests. Take a look at it. It also fixes #2706 (inspect) and #6497 (bindAsEventListener).

It now uses the sandboxing technique to make private methods (_observeAndCache, _extend) and properties (observers array) really private.

If someone tested in Safari that'd be neat!

11/29/06 08:48:03 changed by mislav

  • attachment event.2.diff added.

updated & polished with more love

11/29/06 08:54:08 changed by mislav

  • attachment event.html added.

11/29/06 09:14:18 changed by mislav

I have updated the patch again, adding a killer bonus feature. The module has been given some sweet closure and OOP love. Sneak preview:

observe: function(element, type, observer, useCapture) {
  if (applyToList(arguments)) return;
  
  new Observer(element, type, observer, useCapture).add();
},
stopObserving: function(element, type, observer, useCapture) {
  if (applyToList(arguments)) return;
  
  new Observer(element, type, observer, useCapture).remove();
}

Features so far

  • IE scope correction
  • IE event object normalization
  • IE doesn't error out on Object.inspect(evt) anymore (#2706)
  • bindAsEventListener fix from #6497
  • you can call observe and stopObserving with a collection (array) of elements! For instance you can pass this as an element: $A($('list').childNodes)
  • killer feature: if you omit the handler function from stopObserving(), it removes all the observers of given type from the element, or all the observers of any type if type isn't specified! Wow!! For instance, do this to clean out everything from an element: $('foo').stopObserving()

Tests

Every feature has tests. Download the updated event.html. I ran them on FF2, Opera 8.5 and IE6. I tested for memleaks with IE Sieve. More tests to come.

(follow-ups: ↓ 11 ↓ 12 ) 12/05/06 18:54:19 changed by madrobby

This is proceeding pretty nicely. Some thoughts:

* Move UA detection to a higher-up level, so it's useful elsewhere (there are a few UA tests here and there). On some sites, when I need it, I use an Engine object that can be queried by doing if(Engine.isMSIE) ... and so on and so forth. * Maybe we can find a way to solve #4957 * Add events unit testing (possibly with mock objects, see my comment above)

Anyway, great stuff coming here. :)

(in reply to: ↑ 10 ) 12/05/06 19:20:55 changed by mislav

Replying to madrobby:

Move UA detection to a higher-up level, so it's useful elsewhere

I was thinking about that... but where? And wouldn't people start abusing that detection if it would be a part of the framework?

Maybe we can find a way to solve #4957

I don't have OS X to test, but I can try and others (you?) can test for me

Anyway, great stuff coming here. :)

Thanks!

(in reply to: ↑ 10 ) 12/08/06 17:17:53 changed by savetheclocktower

Replying to madrobby:

Move UA detection to a higher-up level, so it's useful elsewhere

I just submitted #6800 to address this. Let me know what you think.

02/11/07 17:17:25 changed by savetheclocktower

  • cc changed from mislav to mislav, savetheclocktower.

02/28/07 23:56:51 changed by handcoding

  • cc changed from mislav, savetheclocktower to mislav, savetheclocktower, handcoding.

06/14/07 00:37:53 changed by Tobie

  • keywords changed from event ie scope to 1.6 fixedinbranch.

08/18/07 16:17:08 changed by mislav

  • status changed from reopened to closed.
  • resolution set to fixed.