selector.js (60394B)
1 define( [ 2 "./core", 3 "./core/nodeName", 4 "./var/arr", 5 "./var/document", 6 "./var/indexOf", 7 "./var/hasOwn", 8 "./var/pop", 9 "./var/push", 10 "./var/slice", 11 "./var/sort", 12 "./var/splice", 13 "./var/whitespace", 14 "./var/rtrimCSS", 15 "./var/support", 16 17 // The following utils are attached directly to the jQuery object. 18 "./selector/contains", 19 "./selector/escapeSelector" 20 ], function( jQuery, nodeName, arr, document, indexOf, hasOwn, pop, push, 21 slice, sort, splice, whitespace, rtrimCSS, support ) { 22 23 "use strict"; 24 25 var preferredDoc = document, 26 pushNative = push; 27 28 ( function() { 29 30 var i, 31 Expr, 32 outermostContext, 33 sortInput, 34 hasDuplicate, 35 push = pushNative, 36 37 // Local document vars 38 document, 39 documentElement, 40 documentIsHTML, 41 rbuggyQSA, 42 matches, 43 44 // Instance-specific data 45 expando = jQuery.expando, 46 dirruns = 0, 47 done = 0, 48 classCache = createCache(), 49 tokenCache = createCache(), 50 compilerCache = createCache(), 51 nonnativeSelectorCache = createCache(), 52 sortOrder = function( a, b ) { 53 if ( a === b ) { 54 hasDuplicate = true; 55 } 56 return 0; 57 }, 58 59 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + 60 "loop|multiple|open|readonly|required|scoped", 61 62 // Regular expressions 63 64 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 65 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 66 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 67 68 // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors 69 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 70 71 // Operator (capture 2) 72 "*([*^$|!~]?=)" + whitespace + 73 74 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 75 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 76 whitespace + "*\\]", 77 78 pseudos = ":(" + identifier + ")(?:\\((" + 79 80 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 81 // 1. quoted (capture 3; capture 4 or capture 5) 82 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 83 84 // 2. simple (capture 6) 85 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 86 87 // 3. anything else (capture 2) 88 ".*" + 89 ")\\)|)", 90 91 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 92 rwhitespace = new RegExp( whitespace + "+", "g" ), 93 94 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 95 rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + 96 whitespace + "*" ), 97 rdescend = new RegExp( whitespace + "|>" ), 98 99 rpseudo = new RegExp( pseudos ), 100 ridentifier = new RegExp( "^" + identifier + "$" ), 101 102 matchExpr = { 103 ID: new RegExp( "^#(" + identifier + ")" ), 104 CLASS: new RegExp( "^\\.(" + identifier + ")" ), 105 TAG: new RegExp( "^(" + identifier + "|[*])" ), 106 ATTR: new RegExp( "^" + attributes ), 107 PSEUDO: new RegExp( "^" + pseudos ), 108 CHILD: new RegExp( 109 "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 110 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 111 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 112 bool: new RegExp( "^(?:" + booleans + ")$", "i" ), 113 114 // For use in libraries implementing .is() 115 // We use this for POS matching in `select` 116 needsContext: new RegExp( "^" + whitespace + 117 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 118 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 119 }, 120 121 rinputs = /^(?:input|select|textarea|button)$/i, 122 rheader = /^h\d$/i, 123 124 // Easily-parseable/retrievable ID or TAG or CLASS selectors 125 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 126 127 rsibling = /[+~]/, 128 129 // CSS escapes 130 // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters 131 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + 132 "?|\\\\([^\\r\\n\\f])", "g" ), 133 funescape = function( escape, nonHex ) { 134 var high = "0x" + escape.slice( 1 ) - 0x10000; 135 136 if ( nonHex ) { 137 138 // Strip the backslash prefix from a non-hex escape sequence 139 return nonHex; 140 } 141 142 // Replace a hexadecimal escape sequence with the encoded Unicode code point 143 // Support: IE <=11+ 144 // For values outside the Basic Multilingual Plane (BMP), manually construct a 145 // surrogate pair 146 return high < 0 ? 147 String.fromCharCode( high + 0x10000 ) : 148 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 149 }, 150 151 // Used for iframes; see `setDocument`. 152 // Support: IE 9 - 11+, Edge 12 - 18+ 153 // Removing the function wrapper causes a "Permission Denied" 154 // error in IE/Edge. 155 unloadHandler = function() { 156 setDocument(); 157 }, 158 159 inDisabledFieldset = addCombinator( 160 function( elem ) { 161 return elem.disabled === true && nodeName( elem, "fieldset" ); 162 }, 163 { dir: "parentNode", next: "legend" } 164 ); 165 166 // Support: IE <=9 only 167 // Accessing document.activeElement can throw unexpectedly 168 // https://bugs.jquery.com/ticket/13393 169 function safeActiveElement() { 170 try { 171 return document.activeElement; 172 } catch ( err ) { } 173 } 174 175 // Optimize for push.apply( _, NodeList ) 176 try { 177 push.apply( 178 ( arr = slice.call( preferredDoc.childNodes ) ), 179 preferredDoc.childNodes 180 ); 181 182 // Support: Android <=4.0 183 // Detect silently failing push.apply 184 // eslint-disable-next-line no-unused-expressions 185 arr[ preferredDoc.childNodes.length ].nodeType; 186 } catch ( e ) { 187 push = { 188 apply: function( target, els ) { 189 pushNative.apply( target, slice.call( els ) ); 190 }, 191 call: function( target ) { 192 pushNative.apply( target, slice.call( arguments, 1 ) ); 193 } 194 }; 195 } 196 197 function find( selector, context, results, seed ) { 198 var m, i, elem, nid, match, groups, newSelector, 199 newContext = context && context.ownerDocument, 200 201 // nodeType defaults to 9, since context defaults to document 202 nodeType = context ? context.nodeType : 9; 203 204 results = results || []; 205 206 // Return early from calls with invalid selector or context 207 if ( typeof selector !== "string" || !selector || 208 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 209 210 return results; 211 } 212 213 // Try to shortcut find operations (as opposed to filters) in HTML documents 214 if ( !seed ) { 215 setDocument( context ); 216 context = context || document; 217 218 if ( documentIsHTML ) { 219 220 // If the selector is sufficiently simple, try using a "get*By*" DOM method 221 // (excepting DocumentFragment context, where the methods don't exist) 222 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 223 224 // ID selector 225 if ( ( m = match[ 1 ] ) ) { 226 227 // Document context 228 if ( nodeType === 9 ) { 229 if ( ( elem = context.getElementById( m ) ) ) { 230 231 // Support: IE 9 only 232 // getElementById can match elements by name instead of ID 233 if ( elem.id === m ) { 234 push.call( results, elem ); 235 return results; 236 } 237 } else { 238 return results; 239 } 240 241 // Element context 242 } else { 243 244 // Support: IE 9 only 245 // getElementById can match elements by name instead of ID 246 if ( newContext && ( elem = newContext.getElementById( m ) ) && 247 find.contains( context, elem ) && 248 elem.id === m ) { 249 250 push.call( results, elem ); 251 return results; 252 } 253 } 254 255 // Type selector 256 } else if ( match[ 2 ] ) { 257 push.apply( results, context.getElementsByTagName( selector ) ); 258 return results; 259 260 // Class selector 261 } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { 262 push.apply( results, context.getElementsByClassName( m ) ); 263 return results; 264 } 265 } 266 267 // Take advantage of querySelectorAll 268 if ( !nonnativeSelectorCache[ selector + " " ] && 269 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { 270 271 newSelector = selector; 272 newContext = context; 273 274 // qSA considers elements outside a scoping root when evaluating child or 275 // descendant combinators, which is not what we want. 276 // In such cases, we work around the behavior by prefixing every selector in the 277 // list with an ID selector referencing the scope context. 278 // The technique has to be used as well when a leading combinator is used 279 // as such selectors are not recognized by querySelectorAll. 280 // Thanks to Andrew Dupont for this technique. 281 if ( nodeType === 1 && 282 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { 283 284 // Expand context for sibling selectors 285 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 286 context; 287 288 // We can use :scope instead of the ID hack if the browser 289 // supports it & if we're not changing the context. 290 // Support: IE 11+, Edge 17 - 18+ 291 // IE/Edge sometimes throw a "Permission denied" error when 292 // strict-comparing two documents; shallow comparisons work. 293 // eslint-disable-next-line eqeqeq 294 if ( newContext != context || !support.scope ) { 295 296 // Capture the context ID, setting it first if necessary 297 if ( ( nid = context.getAttribute( "id" ) ) ) { 298 nid = jQuery.escapeSelector( nid ); 299 } else { 300 context.setAttribute( "id", ( nid = expando ) ); 301 } 302 } 303 304 // Prefix every selector in the list 305 groups = tokenize( selector ); 306 i = groups.length; 307 while ( i-- ) { 308 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 309 toSelector( groups[ i ] ); 310 } 311 newSelector = groups.join( "," ); 312 } 313 314 try { 315 push.apply( results, 316 newContext.querySelectorAll( newSelector ) 317 ); 318 return results; 319 } catch ( qsaError ) { 320 nonnativeSelectorCache( selector, true ); 321 } finally { 322 if ( nid === expando ) { 323 context.removeAttribute( "id" ); 324 } 325 } 326 } 327 } 328 } 329 330 // All others 331 return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); 332 } 333 334 /** 335 * Create key-value caches of limited size 336 * @returns {function(string, object)} Returns the Object data after storing it on itself with 337 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 338 * deleting the oldest entry 339 */ 340 function createCache() { 341 var keys = []; 342 343 function cache( key, value ) { 344 345 // Use (key + " ") to avoid collision with native prototype properties 346 // (see https://github.com/jquery/sizzle/issues/157) 347 if ( keys.push( key + " " ) > Expr.cacheLength ) { 348 349 // Only keep the most recent entries 350 delete cache[ keys.shift() ]; 351 } 352 return ( cache[ key + " " ] = value ); 353 } 354 return cache; 355 } 356 357 /** 358 * Mark a function for special use by jQuery selector module 359 * @param {Function} fn The function to mark 360 */ 361 function markFunction( fn ) { 362 fn[ expando ] = true; 363 return fn; 364 } 365 366 /** 367 * Support testing using an element 368 * @param {Function} fn Passed the created element and returns a boolean result 369 */ 370 function assert( fn ) { 371 var el = document.createElement( "fieldset" ); 372 373 try { 374 return !!fn( el ); 375 } catch ( e ) { 376 return false; 377 } finally { 378 379 // Remove from its parent by default 380 if ( el.parentNode ) { 381 el.parentNode.removeChild( el ); 382 } 383 384 // release memory in IE 385 el = null; 386 } 387 } 388 389 /** 390 * Returns a function to use in pseudos for input types 391 * @param {String} type 392 */ 393 function createInputPseudo( type ) { 394 return function( elem ) { 395 return nodeName( elem, "input" ) && elem.type === type; 396 }; 397 } 398 399 /** 400 * Returns a function to use in pseudos for buttons 401 * @param {String} type 402 */ 403 function createButtonPseudo( type ) { 404 return function( elem ) { 405 return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && 406 elem.type === type; 407 }; 408 } 409 410 /** 411 * Returns a function to use in pseudos for :enabled/:disabled 412 * @param {Boolean} disabled true for :disabled; false for :enabled 413 */ 414 function createDisabledPseudo( disabled ) { 415 416 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 417 return function( elem ) { 418 419 // Only certain elements can match :enabled or :disabled 420 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 421 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 422 if ( "form" in elem ) { 423 424 // Check for inherited disabledness on relevant non-disabled elements: 425 // * listed form-associated elements in a disabled fieldset 426 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 427 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 428 // * option elements in a disabled optgroup 429 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 430 // All such elements have a "form" property. 431 if ( elem.parentNode && elem.disabled === false ) { 432 433 // Option elements defer to a parent optgroup if present 434 if ( "label" in elem ) { 435 if ( "label" in elem.parentNode ) { 436 return elem.parentNode.disabled === disabled; 437 } else { 438 return elem.disabled === disabled; 439 } 440 } 441 442 // Support: IE 6 - 11+ 443 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 444 return elem.isDisabled === disabled || 445 446 // Where there is no isDisabled, check manually 447 elem.isDisabled !== !disabled && 448 inDisabledFieldset( elem ) === disabled; 449 } 450 451 return elem.disabled === disabled; 452 453 // Try to winnow out elements that can't be disabled before trusting the disabled property. 454 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 455 // even exist on them, let alone have a boolean value. 456 } else if ( "label" in elem ) { 457 return elem.disabled === disabled; 458 } 459 460 // Remaining elements are neither :enabled nor :disabled 461 return false; 462 }; 463 } 464 465 /** 466 * Returns a function to use in pseudos for positionals 467 * @param {Function} fn 468 */ 469 function createPositionalPseudo( fn ) { 470 return markFunction( function( argument ) { 471 argument = +argument; 472 return markFunction( function( seed, matches ) { 473 var j, 474 matchIndexes = fn( [], seed.length, argument ), 475 i = matchIndexes.length; 476 477 // Match elements found at the specified indexes 478 while ( i-- ) { 479 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 480 seed[ j ] = !( matches[ j ] = seed[ j ] ); 481 } 482 } 483 } ); 484 } ); 485 } 486 487 /** 488 * Checks a node for validity as a jQuery selector context 489 * @param {Element|Object=} context 490 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 491 */ 492 function testContext( context ) { 493 return context && typeof context.getElementsByTagName !== "undefined" && context; 494 } 495 496 /** 497 * Sets document-related variables once based on the current document 498 * @param {Element|Object} [node] An element or document object to use to set the document 499 * @returns {Object} Returns the current document 500 */ 501 function setDocument( node ) { 502 var subWindow, 503 doc = node ? node.ownerDocument || node : preferredDoc; 504 505 // Return early if doc is invalid or already selected 506 // Support: IE 11+, Edge 17 - 18+ 507 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 508 // two documents; shallow comparisons work. 509 // eslint-disable-next-line eqeqeq 510 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 511 return document; 512 } 513 514 // Update global variables 515 document = doc; 516 documentElement = document.documentElement; 517 documentIsHTML = !jQuery.isXMLDoc( document ); 518 519 // Support: iOS 7 only, IE 9 - 11+ 520 // Older browsers didn't support unprefixed `matches`. 521 matches = documentElement.matches || 522 documentElement.webkitMatchesSelector || 523 documentElement.msMatchesSelector; 524 525 // Support: IE 9 - 11+, Edge 12 - 18+ 526 // Accessing iframe documents after unload throws "permission denied" errors 527 // (see trac-13936). 528 // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, 529 // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. 530 if ( documentElement.msMatchesSelector && 531 532 // Support: IE 11+, Edge 17 - 18+ 533 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 534 // two documents; shallow comparisons work. 535 // eslint-disable-next-line eqeqeq 536 preferredDoc != document && 537 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 538 539 // Support: IE 9 - 11+, Edge 12 - 18+ 540 subWindow.addEventListener( "unload", unloadHandler ); 541 } 542 543 // Support: IE <10 544 // Check if getElementById returns elements by name 545 // The broken getElementById methods don't pick up programmatically-set names, 546 // so use a roundabout getElementsByName test 547 support.getById = assert( function( el ) { 548 documentElement.appendChild( el ).id = jQuery.expando; 549 return !document.getElementsByName || 550 !document.getElementsByName( jQuery.expando ).length; 551 } ); 552 553 // Support: IE 9 only 554 // Check to see if it's possible to do matchesSelector 555 // on a disconnected node. 556 support.disconnectedMatch = assert( function( el ) { 557 return matches.call( el, "*" ); 558 } ); 559 560 // Support: IE 9 - 11+, Edge 12 - 18+ 561 // IE/Edge don't support the :scope pseudo-class. 562 support.scope = assert( function() { 563 return document.querySelectorAll( ":scope" ); 564 } ); 565 566 // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only 567 // Make sure the `:has()` argument is parsed unforgivingly. 568 // We include `*` in the test to detect buggy implementations that are 569 // _selectively_ forgiving (specifically when the list includes at least 570 // one valid selector). 571 // Note that we treat complete lack of support for `:has()` as if it were 572 // spec-compliant support, which is fine because use of `:has()` in such 573 // environments will fail in the qSA path and fall back to jQuery traversal 574 // anyway. 575 support.cssHas = assert( function() { 576 try { 577 document.querySelector( ":has(*,:jqfake)" ); 578 return false; 579 } catch ( e ) { 580 return true; 581 } 582 } ); 583 584 // ID filter and find 585 if ( support.getById ) { 586 Expr.filter.ID = function( id ) { 587 var attrId = id.replace( runescape, funescape ); 588 return function( elem ) { 589 return elem.getAttribute( "id" ) === attrId; 590 }; 591 }; 592 Expr.find.ID = function( id, context ) { 593 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 594 var elem = context.getElementById( id ); 595 return elem ? [ elem ] : []; 596 } 597 }; 598 } else { 599 Expr.filter.ID = function( id ) { 600 var attrId = id.replace( runescape, funescape ); 601 return function( elem ) { 602 var node = typeof elem.getAttributeNode !== "undefined" && 603 elem.getAttributeNode( "id" ); 604 return node && node.value === attrId; 605 }; 606 }; 607 608 // Support: IE 6 - 7 only 609 // getElementById is not reliable as a find shortcut 610 Expr.find.ID = function( id, context ) { 611 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 612 var node, i, elems, 613 elem = context.getElementById( id ); 614 615 if ( elem ) { 616 617 // Verify the id attribute 618 node = elem.getAttributeNode( "id" ); 619 if ( node && node.value === id ) { 620 return [ elem ]; 621 } 622 623 // Fall back on getElementsByName 624 elems = context.getElementsByName( id ); 625 i = 0; 626 while ( ( elem = elems[ i++ ] ) ) { 627 node = elem.getAttributeNode( "id" ); 628 if ( node && node.value === id ) { 629 return [ elem ]; 630 } 631 } 632 } 633 634 return []; 635 } 636 }; 637 } 638 639 // Tag 640 Expr.find.TAG = function( tag, context ) { 641 if ( typeof context.getElementsByTagName !== "undefined" ) { 642 return context.getElementsByTagName( tag ); 643 644 // DocumentFragment nodes don't have gEBTN 645 } else { 646 return context.querySelectorAll( tag ); 647 } 648 }; 649 650 // Class 651 Expr.find.CLASS = function( className, context ) { 652 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 653 return context.getElementsByClassName( className ); 654 } 655 }; 656 657 /* QSA/matchesSelector 658 ---------------------------------------------------------------------- */ 659 660 // QSA and matchesSelector support 661 662 rbuggyQSA = []; 663 664 // Build QSA regex 665 // Regex strategy adopted from Diego Perini 666 assert( function( el ) { 667 668 var input; 669 670 documentElement.appendChild( el ).innerHTML = 671 "<a id='" + expando + "' href='' disabled='disabled'></a>" + 672 "<select id='" + expando + "-\r\\' disabled='disabled'>" + 673 "<option selected=''></option></select>"; 674 675 // Support: iOS <=7 - 8 only 676 // Boolean attributes and "value" are not treated correctly in some XML documents 677 if ( !el.querySelectorAll( "[selected]" ).length ) { 678 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 679 } 680 681 // Support: iOS <=7 - 8 only 682 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 683 rbuggyQSA.push( "~=" ); 684 } 685 686 // Support: iOS 8 only 687 // https://bugs.webkit.org/show_bug.cgi?id=136851 688 // In-page `selector#id sibling-combinator selector` fails 689 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 690 rbuggyQSA.push( ".#.+[+~]" ); 691 } 692 693 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 694 // In some of the document kinds, these selectors wouldn't work natively. 695 // This is probably OK but for backwards compatibility we want to maintain 696 // handling them through jQuery traversal in jQuery 3.x. 697 if ( !el.querySelectorAll( ":checked" ).length ) { 698 rbuggyQSA.push( ":checked" ); 699 } 700 701 // Support: Windows 8 Native Apps 702 // The type and name attributes are restricted during .innerHTML assignment 703 input = document.createElement( "input" ); 704 input.setAttribute( "type", "hidden" ); 705 el.appendChild( input ).setAttribute( "name", "D" ); 706 707 // Support: IE 9 - 11+ 708 // IE's :disabled selector does not pick up the children of disabled fieldsets 709 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 710 // In some of the document kinds, these selectors wouldn't work natively. 711 // This is probably OK but for backwards compatibility we want to maintain 712 // handling them through jQuery traversal in jQuery 3.x. 713 documentElement.appendChild( el ).disabled = true; 714 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 715 rbuggyQSA.push( ":enabled", ":disabled" ); 716 } 717 718 // Support: IE 11+, Edge 15 - 18+ 719 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 720 // Adding a temporary attribute to the document before the selection works 721 // around the issue. 722 // Interestingly, IE 10 & older don't seem to have the issue. 723 input = document.createElement( "input" ); 724 input.setAttribute( "name", "" ); 725 el.appendChild( input ); 726 if ( !el.querySelectorAll( "[name='']" ).length ) { 727 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 728 whitespace + "*(?:''|\"\")" ); 729 } 730 } ); 731 732 if ( !support.cssHas ) { 733 734 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 735 // Our regular `try-catch` mechanism fails to detect natively-unsupported 736 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 737 // in browsers that parse the `:has()` argument as a forgiving selector list. 738 // https://drafts.csswg.org/selectors/#relational now requires the argument 739 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 740 rbuggyQSA.push( ":has" ); 741 } 742 743 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 744 745 /* Sorting 746 ---------------------------------------------------------------------- */ 747 748 // Document order sorting 749 sortOrder = function( a, b ) { 750 751 // Flag for duplicate removal 752 if ( a === b ) { 753 hasDuplicate = true; 754 return 0; 755 } 756 757 // Sort on method existence if only one input has compareDocumentPosition 758 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 759 if ( compare ) { 760 return compare; 761 } 762 763 // Calculate position if both inputs belong to the same document 764 // Support: IE 11+, Edge 17 - 18+ 765 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 766 // two documents; shallow comparisons work. 767 // eslint-disable-next-line eqeqeq 768 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 769 a.compareDocumentPosition( b ) : 770 771 // Otherwise we know they are disconnected 772 1; 773 774 // Disconnected nodes 775 if ( compare & 1 || 776 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 777 778 // Choose the first element that is related to our preferred document 779 // Support: IE 11+, Edge 17 - 18+ 780 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 781 // two documents; shallow comparisons work. 782 // eslint-disable-next-line eqeqeq 783 if ( a === document || a.ownerDocument == preferredDoc && 784 find.contains( preferredDoc, a ) ) { 785 return -1; 786 } 787 788 // Support: IE 11+, Edge 17 - 18+ 789 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 790 // two documents; shallow comparisons work. 791 // eslint-disable-next-line eqeqeq 792 if ( b === document || b.ownerDocument == preferredDoc && 793 find.contains( preferredDoc, b ) ) { 794 return 1; 795 } 796 797 // Maintain original order 798 return sortInput ? 799 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 800 0; 801 } 802 803 return compare & 4 ? -1 : 1; 804 }; 805 806 return document; 807 } 808 809 find.matches = function( expr, elements ) { 810 return find( expr, null, null, elements ); 811 }; 812 813 find.matchesSelector = function( elem, expr ) { 814 setDocument( elem ); 815 816 if ( documentIsHTML && 817 !nonnativeSelectorCache[ expr + " " ] && 818 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 819 820 try { 821 var ret = matches.call( elem, expr ); 822 823 // IE 9's matchesSelector returns false on disconnected nodes 824 if ( ret || support.disconnectedMatch || 825 826 // As well, disconnected nodes are said to be in a document 827 // fragment in IE 9 828 elem.document && elem.document.nodeType !== 11 ) { 829 return ret; 830 } 831 } catch ( e ) { 832 nonnativeSelectorCache( expr, true ); 833 } 834 } 835 836 return find( expr, document, null, [ elem ] ).length > 0; 837 }; 838 839 find.contains = function( context, elem ) { 840 841 // Set document vars if needed 842 // Support: IE 11+, Edge 17 - 18+ 843 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 844 // two documents; shallow comparisons work. 845 // eslint-disable-next-line eqeqeq 846 if ( ( context.ownerDocument || context ) != document ) { 847 setDocument( context ); 848 } 849 return jQuery.contains( context, elem ); 850 }; 851 852 853 find.attr = function( elem, name ) { 854 855 // Set document vars if needed 856 // Support: IE 11+, Edge 17 - 18+ 857 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 858 // two documents; shallow comparisons work. 859 // eslint-disable-next-line eqeqeq 860 if ( ( elem.ownerDocument || elem ) != document ) { 861 setDocument( elem ); 862 } 863 864 var fn = Expr.attrHandle[ name.toLowerCase() ], 865 866 // Don't get fooled by Object.prototype properties (see trac-13807) 867 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 868 fn( elem, name, !documentIsHTML ) : 869 undefined; 870 871 if ( val !== undefined ) { 872 return val; 873 } 874 875 return elem.getAttribute( name ); 876 }; 877 878 find.error = function( msg ) { 879 throw new Error( "Syntax error, unrecognized expression: " + msg ); 880 }; 881 882 /** 883 * Document sorting and removing duplicates 884 * @param {ArrayLike} results 885 */ 886 jQuery.uniqueSort = function( results ) { 887 var elem, 888 duplicates = [], 889 j = 0, 890 i = 0; 891 892 // Unless we *know* we can detect duplicates, assume their presence 893 // 894 // Support: Android <=4.0+ 895 // Testing for detecting duplicates is unpredictable so instead assume we can't 896 // depend on duplicate detection in all browsers without a stable sort. 897 hasDuplicate = !support.sortStable; 898 sortInput = !support.sortStable && slice.call( results, 0 ); 899 sort.call( results, sortOrder ); 900 901 if ( hasDuplicate ) { 902 while ( ( elem = results[ i++ ] ) ) { 903 if ( elem === results[ i ] ) { 904 j = duplicates.push( i ); 905 } 906 } 907 while ( j-- ) { 908 splice.call( results, duplicates[ j ], 1 ); 909 } 910 } 911 912 // Clear input after sorting to release objects 913 // See https://github.com/jquery/sizzle/pull/225 914 sortInput = null; 915 916 return results; 917 }; 918 919 jQuery.fn.uniqueSort = function() { 920 return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); 921 }; 922 923 Expr = jQuery.expr = { 924 925 // Can be adjusted by the user 926 cacheLength: 50, 927 928 createPseudo: markFunction, 929 930 match: matchExpr, 931 932 attrHandle: {}, 933 934 find: {}, 935 936 relative: { 937 ">": { dir: "parentNode", first: true }, 938 " ": { dir: "parentNode" }, 939 "+": { dir: "previousSibling", first: true }, 940 "~": { dir: "previousSibling" } 941 }, 942 943 preFilter: { 944 ATTR: function( match ) { 945 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 946 947 // Move the given value to match[3] whether quoted or unquoted 948 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) 949 .replace( runescape, funescape ); 950 951 if ( match[ 2 ] === "~=" ) { 952 match[ 3 ] = " " + match[ 3 ] + " "; 953 } 954 955 return match.slice( 0, 4 ); 956 }, 957 958 CHILD: function( match ) { 959 960 /* matches from matchExpr["CHILD"] 961 1 type (only|nth|...) 962 2 what (child|of-type) 963 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 964 4 xn-component of xn+y argument ([+-]?\d*n|) 965 5 sign of xn-component 966 6 x of xn-component 967 7 sign of y-component 968 8 y of y-component 969 */ 970 match[ 1 ] = match[ 1 ].toLowerCase(); 971 972 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 973 974 // nth-* requires argument 975 if ( !match[ 3 ] ) { 976 find.error( match[ 0 ] ); 977 } 978 979 // numeric x and y parameters for Expr.filter.CHILD 980 // remember that false/true cast respectively to 0/1 981 match[ 4 ] = +( match[ 4 ] ? 982 match[ 5 ] + ( match[ 6 ] || 1 ) : 983 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) 984 ); 985 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 986 987 // other types prohibit arguments 988 } else if ( match[ 3 ] ) { 989 find.error( match[ 0 ] ); 990 } 991 992 return match; 993 }, 994 995 PSEUDO: function( match ) { 996 var excess, 997 unquoted = !match[ 6 ] && match[ 2 ]; 998 999 if ( matchExpr.CHILD.test( match[ 0 ] ) ) { 1000 return null; 1001 } 1002 1003 // Accept quoted arguments as-is 1004 if ( match[ 3 ] ) { 1005 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 1006 1007 // Strip excess characters from unquoted arguments 1008 } else if ( unquoted && rpseudo.test( unquoted ) && 1009 1010 // Get excess from tokenize (recursively) 1011 ( excess = tokenize( unquoted, true ) ) && 1012 1013 // advance to the next closing parenthesis 1014 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 1015 1016 // excess is a negative index 1017 match[ 0 ] = match[ 0 ].slice( 0, excess ); 1018 match[ 2 ] = unquoted.slice( 0, excess ); 1019 } 1020 1021 // Return only captures needed by the pseudo filter method (type and argument) 1022 return match.slice( 0, 3 ); 1023 } 1024 }, 1025 1026 filter: { 1027 1028 TAG: function( nodeNameSelector ) { 1029 var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1030 return nodeNameSelector === "*" ? 1031 function() { 1032 return true; 1033 } : 1034 function( elem ) { 1035 return nodeName( elem, expectedNodeName ); 1036 }; 1037 }, 1038 1039 CLASS: function( className ) { 1040 var pattern = classCache[ className + " " ]; 1041 1042 return pattern || 1043 ( pattern = new RegExp( "(^|" + whitespace + ")" + className + 1044 "(" + whitespace + "|$)" ) ) && 1045 classCache( className, function( elem ) { 1046 return pattern.test( 1047 typeof elem.className === "string" && elem.className || 1048 typeof elem.getAttribute !== "undefined" && 1049 elem.getAttribute( "class" ) || 1050 "" 1051 ); 1052 } ); 1053 }, 1054 1055 ATTR: function( name, operator, check ) { 1056 return function( elem ) { 1057 var result = find.attr( elem, name ); 1058 1059 if ( result == null ) { 1060 return operator === "!="; 1061 } 1062 if ( !operator ) { 1063 return true; 1064 } 1065 1066 result += ""; 1067 1068 if ( operator === "=" ) { 1069 return result === check; 1070 } 1071 if ( operator === "!=" ) { 1072 return result !== check; 1073 } 1074 if ( operator === "^=" ) { 1075 return check && result.indexOf( check ) === 0; 1076 } 1077 if ( operator === "*=" ) { 1078 return check && result.indexOf( check ) > -1; 1079 } 1080 if ( operator === "$=" ) { 1081 return check && result.slice( -check.length ) === check; 1082 } 1083 if ( operator === "~=" ) { 1084 return ( " " + result.replace( rwhitespace, " " ) + " " ) 1085 .indexOf( check ) > -1; 1086 } 1087 if ( operator === "|=" ) { 1088 return result === check || result.slice( 0, check.length + 1 ) === check + "-"; 1089 } 1090 1091 return false; 1092 }; 1093 }, 1094 1095 CHILD: function( type, what, _argument, first, last ) { 1096 var simple = type.slice( 0, 3 ) !== "nth", 1097 forward = type.slice( -4 ) !== "last", 1098 ofType = what === "of-type"; 1099 1100 return first === 1 && last === 0 ? 1101 1102 // Shortcut for :nth-*(n) 1103 function( elem ) { 1104 return !!elem.parentNode; 1105 } : 1106 1107 function( elem, _context, xml ) { 1108 var cache, outerCache, node, nodeIndex, start, 1109 dir = simple !== forward ? "nextSibling" : "previousSibling", 1110 parent = elem.parentNode, 1111 name = ofType && elem.nodeName.toLowerCase(), 1112 useCache = !xml && !ofType, 1113 diff = false; 1114 1115 if ( parent ) { 1116 1117 // :(first|last|only)-(child|of-type) 1118 if ( simple ) { 1119 while ( dir ) { 1120 node = elem; 1121 while ( ( node = node[ dir ] ) ) { 1122 if ( ofType ? 1123 nodeName( node, name ) : 1124 node.nodeType === 1 ) { 1125 1126 return false; 1127 } 1128 } 1129 1130 // Reverse direction for :only-* (if we haven't yet done so) 1131 start = dir = type === "only" && !start && "nextSibling"; 1132 } 1133 return true; 1134 } 1135 1136 start = [ forward ? parent.firstChild : parent.lastChild ]; 1137 1138 // non-xml :nth-child(...) stores cache data on `parent` 1139 if ( forward && useCache ) { 1140 1141 // Seek `elem` from a previously-cached index 1142 outerCache = parent[ expando ] || ( parent[ expando ] = {} ); 1143 cache = outerCache[ type ] || []; 1144 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1145 diff = nodeIndex && cache[ 2 ]; 1146 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1147 1148 while ( ( node = ++nodeIndex && node && node[ dir ] || 1149 1150 // Fallback to seeking `elem` from the start 1151 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1152 1153 // When found, cache indexes on `parent` and break 1154 if ( node.nodeType === 1 && ++diff && node === elem ) { 1155 outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 1156 break; 1157 } 1158 } 1159 1160 } else { 1161 1162 // Use previously-cached element index if available 1163 if ( useCache ) { 1164 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 1165 cache = outerCache[ type ] || []; 1166 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1167 diff = nodeIndex; 1168 } 1169 1170 // xml :nth-child(...) 1171 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1172 if ( diff === false ) { 1173 1174 // Use the same loop as above to seek `elem` from the start 1175 while ( ( node = ++nodeIndex && node && node[ dir ] || 1176 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1177 1178 if ( ( ofType ? 1179 nodeName( node, name ) : 1180 node.nodeType === 1 ) && 1181 ++diff ) { 1182 1183 // Cache the index of each encountered element 1184 if ( useCache ) { 1185 outerCache = node[ expando ] || 1186 ( node[ expando ] = {} ); 1187 outerCache[ type ] = [ dirruns, diff ]; 1188 } 1189 1190 if ( node === elem ) { 1191 break; 1192 } 1193 } 1194 } 1195 } 1196 } 1197 1198 // Incorporate the offset, then check against cycle size 1199 diff -= last; 1200 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1201 } 1202 }; 1203 }, 1204 1205 PSEUDO: function( pseudo, argument ) { 1206 1207 // pseudo-class names are case-insensitive 1208 // https://www.w3.org/TR/selectors/#pseudo-classes 1209 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1210 // Remember that setFilters inherits from pseudos 1211 var args, 1212 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1213 find.error( "unsupported pseudo: " + pseudo ); 1214 1215 // The user may use createPseudo to indicate that 1216 // arguments are needed to create the filter function 1217 // just as jQuery does 1218 if ( fn[ expando ] ) { 1219 return fn( argument ); 1220 } 1221 1222 // But maintain support for old signatures 1223 if ( fn.length > 1 ) { 1224 args = [ pseudo, pseudo, "", argument ]; 1225 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1226 markFunction( function( seed, matches ) { 1227 var idx, 1228 matched = fn( seed, argument ), 1229 i = matched.length; 1230 while ( i-- ) { 1231 idx = indexOf.call( seed, matched[ i ] ); 1232 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 1233 } 1234 } ) : 1235 function( elem ) { 1236 return fn( elem, 0, args ); 1237 }; 1238 } 1239 1240 return fn; 1241 } 1242 }, 1243 1244 pseudos: { 1245 1246 // Potentially complex pseudos 1247 not: markFunction( function( selector ) { 1248 1249 // Trim the selector passed to compile 1250 // to avoid treating leading and trailing 1251 // spaces as combinators 1252 var input = [], 1253 results = [], 1254 matcher = compile( selector.replace( rtrimCSS, "$1" ) ); 1255 1256 return matcher[ expando ] ? 1257 markFunction( function( seed, matches, _context, xml ) { 1258 var elem, 1259 unmatched = matcher( seed, null, xml, [] ), 1260 i = seed.length; 1261 1262 // Match elements unmatched by `matcher` 1263 while ( i-- ) { 1264 if ( ( elem = unmatched[ i ] ) ) { 1265 seed[ i ] = !( matches[ i ] = elem ); 1266 } 1267 } 1268 } ) : 1269 function( elem, _context, xml ) { 1270 input[ 0 ] = elem; 1271 matcher( input, null, xml, results ); 1272 1273 // Don't keep the element 1274 // (see https://github.com/jquery/sizzle/issues/299) 1275 input[ 0 ] = null; 1276 return !results.pop(); 1277 }; 1278 } ), 1279 1280 has: markFunction( function( selector ) { 1281 return function( elem ) { 1282 return find( selector, elem ).length > 0; 1283 }; 1284 } ), 1285 1286 contains: markFunction( function( text ) { 1287 text = text.replace( runescape, funescape ); 1288 return function( elem ) { 1289 return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; 1290 }; 1291 } ), 1292 1293 // "Whether an element is represented by a :lang() selector 1294 // is based solely on the element's language value 1295 // being equal to the identifier C, 1296 // or beginning with the identifier C immediately followed by "-". 1297 // The matching of C against the element's language value is performed case-insensitively. 1298 // The identifier C does not have to be a valid language name." 1299 // https://www.w3.org/TR/selectors/#lang-pseudo 1300 lang: markFunction( function( lang ) { 1301 1302 // lang value must be a valid identifier 1303 if ( !ridentifier.test( lang || "" ) ) { 1304 find.error( "unsupported lang: " + lang ); 1305 } 1306 lang = lang.replace( runescape, funescape ).toLowerCase(); 1307 return function( elem ) { 1308 var elemLang; 1309 do { 1310 if ( ( elemLang = documentIsHTML ? 1311 elem.lang : 1312 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 1313 1314 elemLang = elemLang.toLowerCase(); 1315 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1316 } 1317 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 1318 return false; 1319 }; 1320 } ), 1321 1322 // Miscellaneous 1323 target: function( elem ) { 1324 var hash = window.location && window.location.hash; 1325 return hash && hash.slice( 1 ) === elem.id; 1326 }, 1327 1328 root: function( elem ) { 1329 return elem === documentElement; 1330 }, 1331 1332 focus: function( elem ) { 1333 return elem === safeActiveElement() && 1334 document.hasFocus() && 1335 !!( elem.type || elem.href || ~elem.tabIndex ); 1336 }, 1337 1338 // Boolean properties 1339 enabled: createDisabledPseudo( false ), 1340 disabled: createDisabledPseudo( true ), 1341 1342 checked: function( elem ) { 1343 1344 // In CSS3, :checked should return both checked and selected elements 1345 // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1346 return ( nodeName( elem, "input" ) && !!elem.checked ) || 1347 ( nodeName( elem, "option" ) && !!elem.selected ); 1348 }, 1349 1350 selected: function( elem ) { 1351 1352 // Support: IE <=11+ 1353 // Accessing the selectedIndex property 1354 // forces the browser to treat the default option as 1355 // selected when in an optgroup. 1356 if ( elem.parentNode ) { 1357 // eslint-disable-next-line no-unused-expressions 1358 elem.parentNode.selectedIndex; 1359 } 1360 1361 return elem.selected === true; 1362 }, 1363 1364 // Contents 1365 empty: function( elem ) { 1366 1367 // https://www.w3.org/TR/selectors/#empty-pseudo 1368 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1369 // but not by others (comment: 8; processing instruction: 7; etc.) 1370 // nodeType < 6 works because attributes (2) do not appear as children 1371 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1372 if ( elem.nodeType < 6 ) { 1373 return false; 1374 } 1375 } 1376 return true; 1377 }, 1378 1379 parent: function( elem ) { 1380 return !Expr.pseudos.empty( elem ); 1381 }, 1382 1383 // Element/input types 1384 header: function( elem ) { 1385 return rheader.test( elem.nodeName ); 1386 }, 1387 1388 input: function( elem ) { 1389 return rinputs.test( elem.nodeName ); 1390 }, 1391 1392 button: function( elem ) { 1393 return nodeName( elem, "input" ) && elem.type === "button" || 1394 nodeName( elem, "button" ); 1395 }, 1396 1397 text: function( elem ) { 1398 var attr; 1399 return nodeName( elem, "input" ) && elem.type === "text" && 1400 1401 // Support: IE <10 only 1402 // New HTML5 attribute values (e.g., "search") appear 1403 // with elem.type === "text" 1404 ( ( attr = elem.getAttribute( "type" ) ) == null || 1405 attr.toLowerCase() === "text" ); 1406 }, 1407 1408 // Position-in-collection 1409 first: createPositionalPseudo( function() { 1410 return [ 0 ]; 1411 } ), 1412 1413 last: createPositionalPseudo( function( _matchIndexes, length ) { 1414 return [ length - 1 ]; 1415 } ), 1416 1417 eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { 1418 return [ argument < 0 ? argument + length : argument ]; 1419 } ), 1420 1421 even: createPositionalPseudo( function( matchIndexes, length ) { 1422 var i = 0; 1423 for ( ; i < length; i += 2 ) { 1424 matchIndexes.push( i ); 1425 } 1426 return matchIndexes; 1427 } ), 1428 1429 odd: createPositionalPseudo( function( matchIndexes, length ) { 1430 var i = 1; 1431 for ( ; i < length; i += 2 ) { 1432 matchIndexes.push( i ); 1433 } 1434 return matchIndexes; 1435 } ), 1436 1437 lt: createPositionalPseudo( function( matchIndexes, length, argument ) { 1438 var i; 1439 1440 if ( argument < 0 ) { 1441 i = argument + length; 1442 } else if ( argument > length ) { 1443 i = length; 1444 } else { 1445 i = argument; 1446 } 1447 1448 for ( ; --i >= 0; ) { 1449 matchIndexes.push( i ); 1450 } 1451 return matchIndexes; 1452 } ), 1453 1454 gt: createPositionalPseudo( function( matchIndexes, length, argument ) { 1455 var i = argument < 0 ? argument + length : argument; 1456 for ( ; ++i < length; ) { 1457 matchIndexes.push( i ); 1458 } 1459 return matchIndexes; 1460 } ) 1461 } 1462 }; 1463 1464 Expr.pseudos.nth = Expr.pseudos.eq; 1465 1466 // Add button/input type pseudos 1467 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 1468 Expr.pseudos[ i ] = createInputPseudo( i ); 1469 } 1470 for ( i in { submit: true, reset: true } ) { 1471 Expr.pseudos[ i ] = createButtonPseudo( i ); 1472 } 1473 1474 // Easy API for creating new setFilters 1475 function setFilters() {} 1476 setFilters.prototype = Expr.filters = Expr.pseudos; 1477 Expr.setFilters = new setFilters(); 1478 1479 function tokenize( selector, parseOnly ) { 1480 var matched, match, tokens, type, 1481 soFar, groups, preFilters, 1482 cached = tokenCache[ selector + " " ]; 1483 1484 if ( cached ) { 1485 return parseOnly ? 0 : cached.slice( 0 ); 1486 } 1487 1488 soFar = selector; 1489 groups = []; 1490 preFilters = Expr.preFilter; 1491 1492 while ( soFar ) { 1493 1494 // Comma and first run 1495 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 1496 if ( match ) { 1497 1498 // Don't consume trailing commas as valid 1499 soFar = soFar.slice( match[ 0 ].length ) || soFar; 1500 } 1501 groups.push( ( tokens = [] ) ); 1502 } 1503 1504 matched = false; 1505 1506 // Combinators 1507 if ( ( match = rleadingCombinator.exec( soFar ) ) ) { 1508 matched = match.shift(); 1509 tokens.push( { 1510 value: matched, 1511 1512 // Cast descendant combinators to space 1513 type: match[ 0 ].replace( rtrimCSS, " " ) 1514 } ); 1515 soFar = soFar.slice( matched.length ); 1516 } 1517 1518 // Filters 1519 for ( type in Expr.filter ) { 1520 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 1521 ( match = preFilters[ type ]( match ) ) ) ) { 1522 matched = match.shift(); 1523 tokens.push( { 1524 value: matched, 1525 type: type, 1526 matches: match 1527 } ); 1528 soFar = soFar.slice( matched.length ); 1529 } 1530 } 1531 1532 if ( !matched ) { 1533 break; 1534 } 1535 } 1536 1537 // Return the length of the invalid excess 1538 // if we're just parsing 1539 // Otherwise, throw an error or return tokens 1540 if ( parseOnly ) { 1541 return soFar.length; 1542 } 1543 1544 return soFar ? 1545 find.error( selector ) : 1546 1547 // Cache the tokens 1548 tokenCache( selector, groups ).slice( 0 ); 1549 } 1550 1551 function toSelector( tokens ) { 1552 var i = 0, 1553 len = tokens.length, 1554 selector = ""; 1555 for ( ; i < len; i++ ) { 1556 selector += tokens[ i ].value; 1557 } 1558 return selector; 1559 } 1560 1561 function addCombinator( matcher, combinator, base ) { 1562 var dir = combinator.dir, 1563 skip = combinator.next, 1564 key = skip || dir, 1565 checkNonElements = base && key === "parentNode", 1566 doneName = done++; 1567 1568 return combinator.first ? 1569 1570 // Check against closest ancestor/preceding element 1571 function( elem, context, xml ) { 1572 while ( ( elem = elem[ dir ] ) ) { 1573 if ( elem.nodeType === 1 || checkNonElements ) { 1574 return matcher( elem, context, xml ); 1575 } 1576 } 1577 return false; 1578 } : 1579 1580 // Check against all ancestor/preceding elements 1581 function( elem, context, xml ) { 1582 var oldCache, outerCache, 1583 newCache = [ dirruns, doneName ]; 1584 1585 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 1586 if ( xml ) { 1587 while ( ( elem = elem[ dir ] ) ) { 1588 if ( elem.nodeType === 1 || checkNonElements ) { 1589 if ( matcher( elem, context, xml ) ) { 1590 return true; 1591 } 1592 } 1593 } 1594 } else { 1595 while ( ( elem = elem[ dir ] ) ) { 1596 if ( elem.nodeType === 1 || checkNonElements ) { 1597 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 1598 1599 if ( skip && nodeName( elem, skip ) ) { 1600 elem = elem[ dir ] || elem; 1601 } else if ( ( oldCache = outerCache[ key ] ) && 1602 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 1603 1604 // Assign to newCache so results back-propagate to previous elements 1605 return ( newCache[ 2 ] = oldCache[ 2 ] ); 1606 } else { 1607 1608 // Reuse newcache so results back-propagate to previous elements 1609 outerCache[ key ] = newCache; 1610 1611 // A match means we're done; a fail means we have to keep checking 1612 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 1613 return true; 1614 } 1615 } 1616 } 1617 } 1618 } 1619 return false; 1620 }; 1621 } 1622 1623 function elementMatcher( matchers ) { 1624 return matchers.length > 1 ? 1625 function( elem, context, xml ) { 1626 var i = matchers.length; 1627 while ( i-- ) { 1628 if ( !matchers[ i ]( elem, context, xml ) ) { 1629 return false; 1630 } 1631 } 1632 return true; 1633 } : 1634 matchers[ 0 ]; 1635 } 1636 1637 function multipleContexts( selector, contexts, results ) { 1638 var i = 0, 1639 len = contexts.length; 1640 for ( ; i < len; i++ ) { 1641 find( selector, contexts[ i ], results ); 1642 } 1643 return results; 1644 } 1645 1646 function condense( unmatched, map, filter, context, xml ) { 1647 var elem, 1648 newUnmatched = [], 1649 i = 0, 1650 len = unmatched.length, 1651 mapped = map != null; 1652 1653 for ( ; i < len; i++ ) { 1654 if ( ( elem = unmatched[ i ] ) ) { 1655 if ( !filter || filter( elem, context, xml ) ) { 1656 newUnmatched.push( elem ); 1657 if ( mapped ) { 1658 map.push( i ); 1659 } 1660 } 1661 } 1662 } 1663 1664 return newUnmatched; 1665 } 1666 1667 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 1668 if ( postFilter && !postFilter[ expando ] ) { 1669 postFilter = setMatcher( postFilter ); 1670 } 1671 if ( postFinder && !postFinder[ expando ] ) { 1672 postFinder = setMatcher( postFinder, postSelector ); 1673 } 1674 return markFunction( function( seed, results, context, xml ) { 1675 var temp, i, elem, matcherOut, 1676 preMap = [], 1677 postMap = [], 1678 preexisting = results.length, 1679 1680 // Get initial elements from seed or context 1681 elems = seed || 1682 multipleContexts( selector || "*", 1683 context.nodeType ? [ context ] : context, [] ), 1684 1685 // Prefilter to get matcher input, preserving a map for seed-results synchronization 1686 matcherIn = preFilter && ( seed || !selector ) ? 1687 condense( elems, preMap, preFilter, context, xml ) : 1688 elems; 1689 1690 if ( matcher ) { 1691 1692 // If we have a postFinder, or filtered seed, or non-seed postFilter 1693 // or preexisting results, 1694 matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 1695 1696 // ...intermediate processing is necessary 1697 [] : 1698 1699 // ...otherwise use results directly 1700 results; 1701 1702 // Find primary matches 1703 matcher( matcherIn, matcherOut, context, xml ); 1704 } else { 1705 matcherOut = matcherIn; 1706 } 1707 1708 // Apply postFilter 1709 if ( postFilter ) { 1710 temp = condense( matcherOut, postMap ); 1711 postFilter( temp, [], context, xml ); 1712 1713 // Un-match failing elements by moving them back to matcherIn 1714 i = temp.length; 1715 while ( i-- ) { 1716 if ( ( elem = temp[ i ] ) ) { 1717 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 1718 } 1719 } 1720 } 1721 1722 if ( seed ) { 1723 if ( postFinder || preFilter ) { 1724 if ( postFinder ) { 1725 1726 // Get the final matcherOut by condensing this intermediate into postFinder contexts 1727 temp = []; 1728 i = matcherOut.length; 1729 while ( i-- ) { 1730 if ( ( elem = matcherOut[ i ] ) ) { 1731 1732 // Restore matcherIn since elem is not yet a final match 1733 temp.push( ( matcherIn[ i ] = elem ) ); 1734 } 1735 } 1736 postFinder( null, ( matcherOut = [] ), temp, xml ); 1737 } 1738 1739 // Move matched elements from seed to results to keep them synchronized 1740 i = matcherOut.length; 1741 while ( i-- ) { 1742 if ( ( elem = matcherOut[ i ] ) && 1743 ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { 1744 1745 seed[ temp ] = !( results[ temp ] = elem ); 1746 } 1747 } 1748 } 1749 1750 // Add elements to results, through postFinder if defined 1751 } else { 1752 matcherOut = condense( 1753 matcherOut === results ? 1754 matcherOut.splice( preexisting, matcherOut.length ) : 1755 matcherOut 1756 ); 1757 if ( postFinder ) { 1758 postFinder( null, results, matcherOut, xml ); 1759 } else { 1760 push.apply( results, matcherOut ); 1761 } 1762 } 1763 } ); 1764 } 1765 1766 function matcherFromTokens( tokens ) { 1767 var checkContext, matcher, j, 1768 len = tokens.length, 1769 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 1770 implicitRelative = leadingRelative || Expr.relative[ " " ], 1771 i = leadingRelative ? 1 : 0, 1772 1773 // The foundational matcher ensures that elements are reachable from top-level context(s) 1774 matchContext = addCombinator( function( elem ) { 1775 return elem === checkContext; 1776 }, implicitRelative, true ), 1777 matchAnyContext = addCombinator( function( elem ) { 1778 return indexOf.call( checkContext, elem ) > -1; 1779 }, implicitRelative, true ), 1780 matchers = [ function( elem, context, xml ) { 1781 1782 // Support: IE 11+, Edge 17 - 18+ 1783 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1784 // two documents; shallow comparisons work. 1785 // eslint-disable-next-line eqeqeq 1786 var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( 1787 ( checkContext = context ).nodeType ? 1788 matchContext( elem, context, xml ) : 1789 matchAnyContext( elem, context, xml ) ); 1790 1791 // Avoid hanging onto element 1792 // (see https://github.com/jquery/sizzle/issues/299) 1793 checkContext = null; 1794 return ret; 1795 } ]; 1796 1797 for ( ; i < len; i++ ) { 1798 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 1799 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 1800 } else { 1801 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 1802 1803 // Return special upon seeing a positional matcher 1804 if ( matcher[ expando ] ) { 1805 1806 // Find the next relative operator (if any) for proper handling 1807 j = ++i; 1808 for ( ; j < len; j++ ) { 1809 if ( Expr.relative[ tokens[ j ].type ] ) { 1810 break; 1811 } 1812 } 1813 return setMatcher( 1814 i > 1 && elementMatcher( matchers ), 1815 i > 1 && toSelector( 1816 1817 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 1818 tokens.slice( 0, i - 1 ) 1819 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 1820 ).replace( rtrimCSS, "$1" ), 1821 matcher, 1822 i < j && matcherFromTokens( tokens.slice( i, j ) ), 1823 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 1824 j < len && toSelector( tokens ) 1825 ); 1826 } 1827 matchers.push( matcher ); 1828 } 1829 } 1830 1831 return elementMatcher( matchers ); 1832 } 1833 1834 function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 1835 var bySet = setMatchers.length > 0, 1836 byElement = elementMatchers.length > 0, 1837 superMatcher = function( seed, context, xml, results, outermost ) { 1838 var elem, j, matcher, 1839 matchedCount = 0, 1840 i = "0", 1841 unmatched = seed && [], 1842 setMatched = [], 1843 contextBackup = outermostContext, 1844 1845 // We must always have either seed elements or outermost context 1846 elems = seed || byElement && Expr.find.TAG( "*", outermost ), 1847 1848 // Use integer dirruns iff this is the outermost matcher 1849 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 1850 len = elems.length; 1851 1852 if ( outermost ) { 1853 1854 // Support: IE 11+, Edge 17 - 18+ 1855 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1856 // two documents; shallow comparisons work. 1857 // eslint-disable-next-line eqeqeq 1858 outermostContext = context == document || context || outermost; 1859 } 1860 1861 // Add elements passing elementMatchers directly to results 1862 // Support: iOS <=7 - 9 only 1863 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching 1864 // elements by id. (see trac-14142) 1865 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 1866 if ( byElement && elem ) { 1867 j = 0; 1868 1869 // Support: IE 11+, Edge 17 - 18+ 1870 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1871 // two documents; shallow comparisons work. 1872 // eslint-disable-next-line eqeqeq 1873 if ( !context && elem.ownerDocument != document ) { 1874 setDocument( elem ); 1875 xml = !documentIsHTML; 1876 } 1877 while ( ( matcher = elementMatchers[ j++ ] ) ) { 1878 if ( matcher( elem, context || document, xml ) ) { 1879 push.call( results, elem ); 1880 break; 1881 } 1882 } 1883 if ( outermost ) { 1884 dirruns = dirrunsUnique; 1885 } 1886 } 1887 1888 // Track unmatched elements for set filters 1889 if ( bySet ) { 1890 1891 // They will have gone through all possible matchers 1892 if ( ( elem = !matcher && elem ) ) { 1893 matchedCount--; 1894 } 1895 1896 // Lengthen the array for every element, matched or not 1897 if ( seed ) { 1898 unmatched.push( elem ); 1899 } 1900 } 1901 } 1902 1903 // `i` is now the count of elements visited above, and adding it to `matchedCount` 1904 // makes the latter nonnegative. 1905 matchedCount += i; 1906 1907 // Apply set filters to unmatched elements 1908 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 1909 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 1910 // no element matchers and no seed. 1911 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 1912 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 1913 // numerically zero. 1914 if ( bySet && i !== matchedCount ) { 1915 j = 0; 1916 while ( ( matcher = setMatchers[ j++ ] ) ) { 1917 matcher( unmatched, setMatched, context, xml ); 1918 } 1919 1920 if ( seed ) { 1921 1922 // Reintegrate element matches to eliminate the need for sorting 1923 if ( matchedCount > 0 ) { 1924 while ( i-- ) { 1925 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 1926 setMatched[ i ] = pop.call( results ); 1927 } 1928 } 1929 } 1930 1931 // Discard index placeholder values to get only actual matches 1932 setMatched = condense( setMatched ); 1933 } 1934 1935 // Add matches to results 1936 push.apply( results, setMatched ); 1937 1938 // Seedless set matches succeeding multiple successful matchers stipulate sorting 1939 if ( outermost && !seed && setMatched.length > 0 && 1940 ( matchedCount + setMatchers.length ) > 1 ) { 1941 1942 jQuery.uniqueSort( results ); 1943 } 1944 } 1945 1946 // Override manipulation of globals by nested matchers 1947 if ( outermost ) { 1948 dirruns = dirrunsUnique; 1949 outermostContext = contextBackup; 1950 } 1951 1952 return unmatched; 1953 }; 1954 1955 return bySet ? 1956 markFunction( superMatcher ) : 1957 superMatcher; 1958 } 1959 1960 function compile( selector, match /* Internal Use Only */ ) { 1961 var i, 1962 setMatchers = [], 1963 elementMatchers = [], 1964 cached = compilerCache[ selector + " " ]; 1965 1966 if ( !cached ) { 1967 1968 // Generate a function of recursive functions that can be used to check each element 1969 if ( !match ) { 1970 match = tokenize( selector ); 1971 } 1972 i = match.length; 1973 while ( i-- ) { 1974 cached = matcherFromTokens( match[ i ] ); 1975 if ( cached[ expando ] ) { 1976 setMatchers.push( cached ); 1977 } else { 1978 elementMatchers.push( cached ); 1979 } 1980 } 1981 1982 // Cache the compiled function 1983 cached = compilerCache( selector, 1984 matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 1985 1986 // Save selector and tokenization 1987 cached.selector = selector; 1988 } 1989 return cached; 1990 } 1991 1992 /** 1993 * A low-level selection function that works with jQuery's compiled 1994 * selector functions 1995 * @param {String|Function} selector A selector or a pre-compiled 1996 * selector function built with jQuery selector compile 1997 * @param {Element} context 1998 * @param {Array} [results] 1999 * @param {Array} [seed] A set of elements to match against 2000 */ 2001 function select( selector, context, results, seed ) { 2002 var i, tokens, token, type, find, 2003 compiled = typeof selector === "function" && selector, 2004 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 2005 2006 results = results || []; 2007 2008 // Try to minimize operations if there is only one selector in the list and no seed 2009 // (the latter of which guarantees us context) 2010 if ( match.length === 1 ) { 2011 2012 // Reduce context if the leading compound selector is an ID 2013 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 2014 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 2015 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 2016 2017 context = ( Expr.find.ID( 2018 token.matches[ 0 ].replace( runescape, funescape ), 2019 context 2020 ) || [] )[ 0 ]; 2021 if ( !context ) { 2022 return results; 2023 2024 // Precompiled matchers will still verify ancestry, so step up a level 2025 } else if ( compiled ) { 2026 context = context.parentNode; 2027 } 2028 2029 selector = selector.slice( tokens.shift().value.length ); 2030 } 2031 2032 // Fetch a seed set for right-to-left matching 2033 i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; 2034 while ( i-- ) { 2035 token = tokens[ i ]; 2036 2037 // Abort if we hit a combinator 2038 if ( Expr.relative[ ( type = token.type ) ] ) { 2039 break; 2040 } 2041 if ( ( find = Expr.find[ type ] ) ) { 2042 2043 // Search, expanding context for leading sibling combinators 2044 if ( ( seed = find( 2045 token.matches[ 0 ].replace( runescape, funescape ), 2046 rsibling.test( tokens[ 0 ].type ) && 2047 testContext( context.parentNode ) || context 2048 ) ) ) { 2049 2050 // If seed is empty or no tokens remain, we can return early 2051 tokens.splice( i, 1 ); 2052 selector = seed.length && toSelector( tokens ); 2053 if ( !selector ) { 2054 push.apply( results, seed ); 2055 return results; 2056 } 2057 2058 break; 2059 } 2060 } 2061 } 2062 } 2063 2064 // Compile and execute a filtering function if one is not provided 2065 // Provide `match` to avoid retokenization if we modified the selector above 2066 ( compiled || compile( selector, match ) )( 2067 seed, 2068 context, 2069 !documentIsHTML, 2070 results, 2071 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2072 ); 2073 return results; 2074 } 2075 2076 // One-time assignments 2077 2078 // Support: Android <=4.0 - 4.1+ 2079 // Sort stability 2080 support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 2081 2082 // Initialize against the default document 2083 setDocument(); 2084 2085 // Support: Android <=4.0 - 4.1+ 2086 // Detached nodes confoundingly follow *each other* 2087 support.sortDetached = assert( function( el ) { 2088 2089 // Should return 1, but returns 4 (following) 2090 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 2091 } ); 2092 2093 jQuery.find = find; 2094 2095 // Deprecated 2096 jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2097 jQuery.unique = jQuery.uniqueSort; 2098 2099 // These have always been private, but they used to be documented as part of 2100 // Sizzle so let's maintain them for now for backwards compatibility purposes. 2101 find.compile = compile; 2102 find.select = select; 2103 find.setDocument = setDocument; 2104 find.tokenize = tokenize; 2105 2106 find.escape = jQuery.escapeSelector; 2107 find.getText = jQuery.text; 2108 find.isXML = jQuery.isXMLDoc; 2109 find.selectors = jQuery.expr; 2110 find.support = jQuery.support; 2111 find.uniqueSort = jQuery.uniqueSort; 2112 2113 /* eslint-enable */ 2114 2115 } )(); 2116 2117 } );