Closed tmpvar closed 8 years ago
This could help with #525's :focus
failure as well.
Actually as of HTML5 all elements have focus
and blur
methods:
http://dev.w3.org/html5/spec/single-page.html#focus-management
This is used in the newest Sizzle tests to focus a random div, interestingly.
O_o .. Ok, well I guess that just makes things easier lol
On Nov 22, 2012, at 12:50 PM, Domenic Denicola notifications@github.com wrote:
Actually as of HTML5 all elements have focus and blur methods:
http://dev.w3.org/html5/spec/single-page.html#focus-management
This is used in the newest Sizzle tests to focus a random div, interestingly.
— Reply to this email directly or view it on GitHub.
Not sure this is important here for JSDOM, nor I know how much could/should be implemented.
In browsers the Activation model takes place too (DOMActivate, DOMFocusIn, DOMFocusOut).
Consider that specs says this is important only if XFORMS or Aria support is required.
Also the above events seems now deprecated, for 2 of them there are replacements: focusin, focusout.
This is a reference for event synthesis in L3:
http://www.w3.org/TR/DOM-Level-3-Events/#click-synthesis
The order in which events happen is in § 5.2.2.1
The main concern that raised in me, after suggesting that patch, is if a transition through the "body" element is always required.
For example, if a text input is currently the activeElement having the keyboard focus and a click is performed on the next text input, the activeElement should transit directly to that target element instead of going through the "body" element (caused by the "blur" event).
This probably too complex for the objective but I wanted to share the doubts :)
I just ran into this. I'd managed to get a jquery.validate signup form fully tested with a manually-created JSDOM document, window etc, until I added validate-on-blur. It took me quite a while to figure out it's because these events aren't firing.
After digging around, it seems Zombie.js solves this problem by monkeypatching JSDOM: https://github.com/assaf/zombie/blob/master/src/zombie/dom_focus.coffee
Sadly there doesn't seem a way to re-use this without copypasting it into my project. (I'm extremely new to JavaScript/Node though, so maybe I've missed something.) Either way, it's a shame to have to use Zombie (or dismembered code thereof) for want of focus events in JSDOM.
Update: I decided to copypaste the Zombie monkeypatch and it works fine. Maybe it'd be possible to port this to JSDOM? I don't know if it's compliant with everything @dperini mentioned above though.
Wow, it looks like Zombie has a lot of patches. I wish they would contribute them back to jsdom.
Just adding a :+1: as another person who could use this functionality.
Here's an approach I took to trigger the basic events. Would this kind of approach be accepted as a patch? If so, where would the tests belong?
activeElement = document.body
Object.defineProperty document, 'activeElement',
get: -> activeElement
set: (newActiveElement) ->
blurEvent = document.createEvent("HTMLEvents")
blurEvent.initEvent("blur", false, false)
focusEvent = document.createEvent("HTMLEvents")
focusEvent.initEvent("focus", false, false)
oldActiveElement = activeElement
activeElement = newActiveElement
oldActiveElement.dispatchEvent(blurEvent)
newActiveElement.dispatchEvent(focusEvent)
No patches written in languages other than JavaScript will be accepted.
I mean the general approach, not the language.
@nathansobo Nice patch! I couldn't get event bubbling to work though, even when switching the bubbles flag on the initEvent calls.
Are there any attempts to get the Zombie patch into JSDOM?
I tried to integrate the zombie.js patch, but in some case, the focus and blur events were not getting triggered. The fix was to remove:
HTML.HTMLElement.prototype.focus = function() {
};
HTML.HTMLElement.prototype.blur = function() {
};
Unfortunately, I was not able to isolate the issue nor able to create a simple reproduction of this error...
It looks like this is still an issue. I have some code that needs to read document.activeElement
in a blur
event handler (since nobody told IE11 about relatedTarget
). In order to test this code using jsdom
, we have to use an extra step:
// 1. Reset document.activeElement (pick one, these are equivalent)
myElement.blur();
document.activeElement = document.body;
// 2. Send an event to call handlers
myElement.dispatchEvent( new Event( 'blur' ) );
Right now we are just changing the
document.activeElement
, but I believe we need to emit events as well.Also, tests.