66 * Released under the MIT license
77 * http://jquery.org/license
88 *
9- * Date: 2015-12-18
9+ * Date: 2016-01-04
1010 */
1111( function ( window ) {
1212
@@ -175,7 +175,14 @@ var i,
175175 // error in IE
176176 unloadHandler = function ( ) {
177177 setDocument ( ) ;
178- } ;
178+ } ,
179+
180+ disabledAncestor = addCombinator (
181+ function ( elem ) {
182+ return elem . disabled === true ;
183+ } ,
184+ { dir : "parentNode" , next : "legend" }
185+ ) ;
179186
180187// Optimize for push.apply( _, NodeList )
181188try {
@@ -370,22 +377,22 @@ function markFunction( fn ) {
370377
371378/**
372379 * Support testing using an element
373- * @param {Function } fn Passed the created div and expects a boolean result
380+ * @param {Function } fn Passed the created element and returns a boolean result
374381 */
375382function assert ( fn ) {
376- var div = document . createElement ( "div " ) ;
383+ var el = document . createElement ( "fieldset " ) ;
377384
378385 try {
379- return ! ! fn ( div ) ;
386+ return ! ! fn ( el ) ;
380387 } catch ( e ) {
381388 return false ;
382389 } finally {
383390 // Remove from its parent by default
384- if ( div . parentNode ) {
385- div . parentNode . removeChild ( div ) ;
391+ if ( el . parentNode ) {
392+ el . parentNode . removeChild ( el ) ;
386393 }
387394 // release memory in IE
388- div = null ;
395+ el = null ;
389396 }
390397}
391398
@@ -453,6 +460,34 @@ function createButtonPseudo( type ) {
453460 } ;
454461}
455462
463+ /**
464+ * Returns a function to use in pseudos for :enabled/:disabled
465+ * @param {Boolean } disabled true for :disabled; false for :enabled
466+ */
467+ function createDisabledPseudo ( disabled ) {
468+ // Known :disabled false positives:
469+ // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)
470+ // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
471+ return function ( elem ) {
472+
473+ // Check form elements and option elements for explicit disabling
474+ return "label" in elem && elem . disabled === disabled ||
475+ "form" in elem && elem . disabled === disabled ||
476+
477+ // Check non-disabled form elements for fieldset[disabled] ancestors
478+ "form" in elem && elem . disabled === false && (
479+ // Support: IE6-11+
480+ // Ancestry is covered for us
481+ elem . isDisabled === disabled ||
482+
483+ // Otherwise, assume any non-<option> under fieldset[disabled] is disabled
484+ /* jshint -W018 */
485+ elem . isDisabled !== ! disabled &&
486+ ( "label" in elem || ! disabledAncestor ( elem ) ) !== disabled
487+ ) ;
488+ } ;
489+ }
490+
456491/**
457492 * Returns a function to use in pseudos for positionals
458493 * @param {Function } fn
@@ -539,18 +574,18 @@ setDocument = Sizzle.setDocument = function( node ) {
539574 // Support: IE<8
540575 // Verify that getAttribute really returns attributes and not properties
541576 // (excepting IE8 booleans)
542- support . attributes = assert ( function ( div ) {
543- div . className = "i" ;
544- return ! div . getAttribute ( "className" ) ;
577+ support . attributes = assert ( function ( el ) {
578+ el . className = "i" ;
579+ return ! el . getAttribute ( "className" ) ;
545580 } ) ;
546581
547582 /* getElement(s)By*
548583 ---------------------------------------------------------------------- */
549584
550585 // Check if getElementsByTagName("*") returns only elements
551- support . getElementsByTagName = assert ( function ( div ) {
552- div . appendChild ( document . createComment ( "" ) ) ;
553- return ! div . getElementsByTagName ( "*" ) . length ;
586+ support . getElementsByTagName = assert ( function ( el ) {
587+ el . appendChild ( document . createComment ( "" ) ) ;
588+ return ! el . getElementsByTagName ( "*" ) . length ;
554589 } ) ;
555590
556591 // Support: IE<9
@@ -560,8 +595,8 @@ setDocument = Sizzle.setDocument = function( node ) {
560595 // Check if getElementById returns elements by name
561596 // The broken getElementById methods don't pick up programmatically-set names,
562597 // so use a roundabout getElementsByName test
563- support . getById = assert ( function ( div ) {
564- docElem . appendChild ( div ) . id = expando ;
598+ support . getById = assert ( function ( el ) {
599+ docElem . appendChild ( el ) . id = expando ;
565600 return ! document . getElementsByName || ! document . getElementsByName ( expando ) . length ;
566601 } ) ;
567602
@@ -651,71 +686,81 @@ setDocument = Sizzle.setDocument = function( node ) {
651686 if ( ( support . qsa = rnative . test ( document . querySelectorAll ) ) ) {
652687 // Build QSA regex
653688 // Regex strategy adopted from Diego Perini
654- assert ( function ( div ) {
689+ assert ( function ( el ) {
655690 // Select is set to empty string on purpose
656691 // This is to test IE's treatment of not explicitly
657692 // setting a boolean content attribute,
658693 // since its presence should be enough
659694 // https://bugs.jquery.com/ticket/12359
660- docElem . appendChild ( div ) . innerHTML = "<a id='" + expando + "'></a>" +
695+ docElem . appendChild ( el ) . innerHTML = "<a id='" + expando + "'></a>" +
661696 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
662697 "<option selected=''></option></select>" ;
663698
664699 // Support: IE8, Opera 11-12.16
665700 // Nothing should be selected when empty strings follow ^= or $= or *=
666701 // The test attribute must be unknown in Opera but "safe" for WinRT
667702 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
668- if ( div . querySelectorAll ( "[msallowcapture^='']" ) . length ) {
703+ if ( el . querySelectorAll ( "[msallowcapture^='']" ) . length ) {
669704 rbuggyQSA . push ( "[*^$]=" + whitespace + "*(?:''|\"\")" ) ;
670705 }
671706
672707 // Support: IE8
673708 // Boolean attributes and "value" are not treated correctly
674- if ( ! div . querySelectorAll ( "[selected]" ) . length ) {
709+ if ( ! el . querySelectorAll ( "[selected]" ) . length ) {
675710 rbuggyQSA . push ( "\\[" + whitespace + "*(?:value|" + booleans + ")" ) ;
676711 }
677712
678713 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
679- if ( ! div . querySelectorAll ( "[id~=" + expando + "-]" ) . length ) {
714+ if ( ! el . querySelectorAll ( "[id~=" + expando + "-]" ) . length ) {
680715 rbuggyQSA . push ( "~=" ) ;
681716 }
682717
683718 // Webkit/Opera - :checked should return selected option elements
684719 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
685720 // IE8 throws error here and will not see later tests
686- if ( ! div . querySelectorAll ( ":checked" ) . length ) {
721+ if ( ! el . querySelectorAll ( ":checked" ) . length ) {
687722 rbuggyQSA . push ( ":checked" ) ;
688723 }
689724
690725 // Support: Safari 8+, iOS 8+
691726 // https://bugs.webkit.org/show_bug.cgi?id=136851
692727 // In-page `selector#id sibling-combinator selector` fails
693- if ( ! div . querySelectorAll ( "a#" + expando + "+*" ) . length ) {
728+ if ( ! el . querySelectorAll ( "a#" + expando + "+*" ) . length ) {
694729 rbuggyQSA . push ( ".#.+[+~]" ) ;
695730 }
696731 } ) ;
697732
698- assert ( function ( div ) {
733+ assert ( function ( el ) {
734+ el . innerHTML = "<a href='' disabled='disabled'></a>" +
735+ "<select disabled='disabled'><option/></select>" ;
736+
699737 // Support: Windows 8 Native Apps
700738 // The type and name attributes are restricted during .innerHTML assignment
701739 var input = document . createElement ( "input" ) ;
702740 input . setAttribute ( "type" , "hidden" ) ;
703- div . appendChild ( input ) . setAttribute ( "name" , "D" ) ;
741+ el . appendChild ( input ) . setAttribute ( "name" , "D" ) ;
704742
705743 // Support: IE8
706744 // Enforce case-sensitivity of name attribute
707- if ( div . querySelectorAll ( "[name=d]" ) . length ) {
745+ if ( el . querySelectorAll ( "[name=d]" ) . length ) {
708746 rbuggyQSA . push ( "name" + whitespace + "*[*^$|!~]?=" ) ;
709747 }
710748
711749 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
712750 // IE8 throws error here and will not see later tests
713- if ( ! div . querySelectorAll ( ":enabled" ) . length ) {
751+ if ( el . querySelectorAll ( ":enabled" ) . length !== 2 ) {
752+ rbuggyQSA . push ( ":enabled" , ":disabled" ) ;
753+ }
754+
755+ // Support: IE9-11+
756+ // IE's :disabled selector does not pick up the children of disabled fieldsets
757+ docElem . appendChild ( el ) . disabled = true ;
758+ if ( el . querySelectorAll ( ":disabled" ) . length !== 2 ) {
714759 rbuggyQSA . push ( ":enabled" , ":disabled" ) ;
715760 }
716761
717762 // Opera 10-11 does not throw on post-comma invalid pseudos
718- div . querySelectorAll ( "*,:x" ) ;
763+ el . querySelectorAll ( "*,:x" ) ;
719764 rbuggyQSA . push ( ",.*:" ) ;
720765 } ) ;
721766 }
@@ -726,14 +771,14 @@ setDocument = Sizzle.setDocument = function( node ) {
726771 docElem . oMatchesSelector ||
727772 docElem . msMatchesSelector ) ) ) ) {
728773
729- assert ( function ( div ) {
774+ assert ( function ( el ) {
730775 // Check to see if it's possible to do matchesSelector
731776 // on a disconnected node (IE 9)
732- support . disconnectedMatch = matches . call ( div , "div " ) ;
777+ support . disconnectedMatch = matches . call ( el , "* " ) ;
733778
734779 // This should fail with an exception
735780 // Gecko does not error, returns false instead
736- matches . call ( div , "[s!='']:x" ) ;
781+ matches . call ( el , "[s!='']:x" ) ;
737782 rbuggyMatches . push ( "!=" , pseudos ) ;
738783 } ) ;
739784 }
@@ -1406,13 +1451,8 @@ Expr = Sizzle.selectors = {
14061451 } ,
14071452
14081453 // Boolean properties
1409- "enabled" : function ( elem ) {
1410- return elem . disabled === false ;
1411- } ,
1412-
1413- "disabled" : function ( elem ) {
1414- return elem . disabled === true ;
1415- } ,
1454+ "enabled" : createDisabledPseudo ( false ) ,
1455+ "disabled" : createDisabledPseudo ( true ) ,
14161456
14171457 "checked" : function ( elem ) {
14181458 // In CSS3, :checked should return both checked and selected elements
@@ -1614,7 +1654,9 @@ function toSelector( tokens ) {
16141654
16151655function addCombinator ( matcher , combinator , base ) {
16161656 var dir = combinator . dir ,
1617- checkNonElements = base && dir === "parentNode" ,
1657+ skip = combinator . next ,
1658+ key = skip || dir ,
1659+ checkNonElements = base && key === "parentNode" ,
16181660 doneName = done ++ ;
16191661
16201662 return combinator . first ?
@@ -1650,14 +1692,16 @@ function addCombinator( matcher, combinator, base ) {
16501692 // Defend against cloned attroperties (jQuery gh-1709)
16511693 uniqueCache = outerCache [ elem . uniqueID ] || ( outerCache [ elem . uniqueID ] = { } ) ;
16521694
1653- if ( ( oldCache = uniqueCache [ dir ] ) &&
1695+ if ( skip && skip === elem . nodeName . toLowerCase ( ) ) {
1696+ elem = elem [ dir ] || elem ;
1697+ } else if ( ( oldCache = uniqueCache [ key ] ) &&
16541698 oldCache [ 0 ] === dirruns && oldCache [ 1 ] === doneName ) {
16551699
16561700 // Assign to newCache so results back-propagate to previous elements
16571701 return ( newCache [ 2 ] = oldCache [ 2 ] ) ;
16581702 } else {
16591703 // Reuse newcache so results back-propagate to previous elements
1660- uniqueCache [ dir ] = newCache ;
1704+ uniqueCache [ key ] = newCache ;
16611705
16621706 // A match means we're done; a fail means we have to keep checking
16631707 if ( ( newCache [ 2 ] = matcher ( elem , context , xml ) ) ) {
@@ -2100,17 +2144,17 @@ setDocument();
21002144
21012145// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
21022146// Detached nodes confoundingly follow *each other*
2103- support . sortDetached = assert ( function ( div1 ) {
2147+ support . sortDetached = assert ( function ( el ) {
21042148 // Should return 1, but returns 4 (following)
2105- return div1 . compareDocumentPosition ( document . createElement ( "div " ) ) & 1 ;
2149+ return el . compareDocumentPosition ( document . createElement ( "fieldset " ) ) & 1 ;
21062150} ) ;
21072151
21082152// Support: IE<8
21092153// Prevent attribute/property "interpolation"
21102154// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2111- if ( ! assert ( function ( div ) {
2112- div . innerHTML = "<a href='#'></a>" ;
2113- return div . firstChild . getAttribute ( "href" ) === "#" ;
2155+ if ( ! assert ( function ( el ) {
2156+ el . innerHTML = "<a href='#'></a>" ;
2157+ return el . firstChild . getAttribute ( "href" ) === "#" ;
21142158} ) ) {
21152159 addHandle ( "type|href|height|width" , function ( elem , name , isXML ) {
21162160 if ( ! isXML ) {
@@ -2121,10 +2165,10 @@ if ( !assert(function( div ) {
21212165
21222166// Support: IE<9
21232167// Use defaultValue in place of getAttribute("value")
2124- if ( ! support . attributes || ! assert ( function ( div ) {
2125- div . innerHTML = "<input/>" ;
2126- div . firstChild . setAttribute ( "value" , "" ) ;
2127- return div . firstChild . getAttribute ( "value" ) === "" ;
2168+ if ( ! support . attributes || ! assert ( function ( el ) {
2169+ el . innerHTML = "<input/>" ;
2170+ el . firstChild . setAttribute ( "value" , "" ) ;
2171+ return el . firstChild . getAttribute ( "value" ) === "" ;
21282172} ) ) {
21292173 addHandle ( "value" , function ( elem , name , isXML ) {
21302174 if ( ! isXML && elem . nodeName . toLowerCase ( ) === "input" ) {
@@ -2135,8 +2179,8 @@ if ( !support.attributes || !assert(function( div ) {
21352179
21362180// Support: IE<9
21372181// Use getAttributeNode to fetch booleans when getAttribute lies
2138- if ( ! assert ( function ( div ) {
2139- return div . getAttribute ( "disabled" ) == null ;
2182+ if ( ! assert ( function ( el ) {
2183+ return el . getAttribute ( "disabled" ) == null ;
21402184} ) ) {
21412185 addHandle ( booleans , function ( elem , name , isXML ) {
21422186 var val ;
0 commit comments