Permalink
Browse files

Check document focus and type/href attributes when determining :focus…

…. Fixes #10809. Add support for the :active pseudo selector.
  • Loading branch information...
1 parent 78f7d36 commit fbef0360e2483e889465610b15c41179e9c0e1e9 timmywil committed May 26, 2012
Showing with 18 additions and 4 deletions.
  1. +7 −1 sizzle.js
  2. +11 −3 test/unit/selector.js
View
@@ -752,7 +752,7 @@ var Expr = Sizzle.selectors = {
match[3] = select(match[3], document, [], curLoop, isXML);
} else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ var ret = Sizzle.filter(match[3], curLoop, inplace, !not);
if ( !inplace ) {
result.push.apply( result, ret );
@@ -861,9 +861,15 @@ var Expr = Sizzle.selectors = {
},
focus: function( elem ) {
@aFarkas
aFarkas Jun 28, 2012

I'm not sure wether this fix is right.

  1. Elements without type/href attribute can't have focus? What is about elements with tabindex? (see also tabindex implementation of jquery: https://github.com/jquery/jquery/blob/aa6f8c8cd399d50e91dc0a3634395b6ebf54b209/src/attributes.js#L408-419)
  2. Accessing the activeElement-property can throw an unspecified script error in IE in conjunction with iframes (see also: jquery/jquery-mobile#2064)
@timmywil
timmywil Jun 28, 2012 Member

Elements that support tabindex have a type or href property. As far as accessing activeElement throwing an error, I wonder if it is worth adding a try/catch in core for such an edge case.

@aFarkas
aFarkas Jun 28, 2012
  1. No: http://dev.w3.org/html5/markup/global-attributes.html#common.attrs.tabindex
  2. I don't understand, what is an edge case here? Loading a page with jQuery inside if an iframe? Or, using the :focus/:active selector (than you really should remove it). I just saw the "new/upcomming" :focus code because I was using :focus in a plugin and someone used this plugin and his site was loaded in an iframe and boom. So, everyone who is using focus and want to make sure, that his/her script also works inside of an iframe has to change his/her code, I really want to see this documented then.
@timmywil
timmywil Jun 29, 2012 Member
  1. Actually, yes. http://www.w3.org/TR/html401/interact/forms.html#adef-tabindex However, I wasn't aware the working draft was making that change. I don't mind adding support for that, but it would be an issue in older browsers where tabindex does not indicate focusable.
  2. I misunderstood the issue. I was thinking iframe:active. Nevertheless, :focus has worked this way since its creation and the only issue filed has been in mobile. Is there a reduced test case somewhere?
@aFarkas
aFarkas Jun 30, 2012

I think, you can build a simple test by testing $('input').is(':focus'); inside an iframed document as soon as possible.

<input />
<script>
    jQuery('input').is(':focus');
</script>

The error is thrown, if the "parentDocument" hasn't finished loading or the iframed document has no focus (I'm not really sure). Normally this bug occurs, if you check :focus on DOM ready.

Something about 1: Microsoft has introduced this with IE5 and all other browsers have integrated this feature about 2-3 years ago.

+ var doc = elem.ownerDocument;
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);
+ },
+
+ active: function( elem ) {
return elem === elem.ownerDocument.activeElement;
}
},
+
setFilters: {
first: function( elem, i ) {
return i === 0;
View
@@ -401,7 +401,7 @@ test("pseudo - child", function() {
});
test("pseudo - misc", function() {
- expect(19);
+ expect(21);
t( "Headers", ":header", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );
@@ -440,7 +440,7 @@ test("pseudo - misc", function() {
// Inputs can't be focused unless the document has focus
if ( document.activeElement !== input || (document.hasFocus && !document.hasFocus()) ||
- (document.querySelectorAll && !document.querySelectorAll('input:focus').length) ) {
+ (document.querySelectorAll && !document.querySelectorAll("input:focus").length) ) {
ok( true, "The input was not focused. Skip checking the :focus match." );
ok( true, "The input was not focused. Skip checking the :focus match." );
@@ -449,14 +449,22 @@ test("pseudo - misc", function() {
ok( (window.Sizzle || window.jQuery.find).matchesSelector( input, ":focus" ), ":focus Matches" );
}
+ // :active selector: this selector does not depend on document focus
+ if ( document.activeElement === input ) {
+ ok( (window.Sizzle || window.jQuery.find).matchesSelector( input, ":active" ), ":active Matches" );
+ } else {
+ ok( true, "The input did not become active. Skip checking the :active match." );
+ }
+
input.blur();
// When IE is out of focus, blur does not work. Force it here.
if ( document.activeElement === input ) {
document.body.focus();
}
- ok( !(window.Sizzle || window.jQuery.find).matchesSelector( input, ":focus" ), ":focus Doesn't Match" );
+ ok( !(window.Sizzle || window.jQuery.find).matchesSelector( input, ":focus" ), ":focus doesn't match" );
+ ok( !(window.Sizzle || window.jQuery.find).matchesSelector( input, ":active" ), ":active doesn't match" );
document.body.removeChild( input );
});

0 comments on commit fbef036

Please sign in to comment.