selector-native.js (5167B)
1 define( [ 2 "./core", 3 "./var/document", 4 "./var/documentElement", 5 "./var/hasOwn", 6 "./var/indexOf", 7 "./var/slice", 8 9 // The following utils are attached directly to the jQuery object. 10 "./selector/contains", 11 "./selector/escapeSelector" 12 ], function( jQuery, document, documentElement, hasOwn, indexOf, slice ) { 13 14 "use strict"; 15 16 /* 17 * Optional limited selector module for custom builds. 18 * 19 * Note that this DOES NOT SUPPORT many documented jQuery 20 * features in exchange for its smaller size: 21 * 22 * * Attribute not equal selector (!=) 23 * * Positional selectors (:first; :eq(n); :odd; etc.) 24 * * Type selectors (:input; :checkbox; :button; etc.) 25 * * State-based selectors (:animated; :visible; :hidden; etc.) 26 * * :has(selector) 27 * * :not(complex selector) 28 * * custom selectors via jQuery extensions 29 * * Leading combinators (e.g., $collection.find("> *")) 30 * * Reliable functionality on XML fragments 31 * * Requiring all parts of a selector to match elements under context 32 * (e.g., $div.find("div > *") now matches children of $div) 33 * * Matching against non-elements 34 * * Reliable sorting of disconnected nodes 35 * * querySelectorAll bug fixes (e.g., unreliable :focus on WebKit) 36 * 37 * If any of these are unacceptable tradeoffs, either use the full 38 * selector engine or customize this stub for the project's specific 39 * needs. 40 */ 41 42 var hasDuplicate, sortInput, 43 sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando, 44 matches = documentElement.matches || 45 documentElement.webkitMatchesSelector || 46 documentElement.msMatchesSelector; 47 48 function sortOrder( a, b ) { 49 50 // Flag for duplicate removal 51 if ( a === b ) { 52 hasDuplicate = true; 53 return 0; 54 } 55 56 // Sort on method existence if only one input has compareDocumentPosition 57 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 58 if ( compare ) { 59 return compare; 60 } 61 62 // Calculate position if both inputs belong to the same document 63 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 64 a.compareDocumentPosition( b ) : 65 66 // Otherwise we know they are disconnected 67 1; 68 69 // Disconnected nodes 70 if ( compare & 1 ) { 71 72 // Choose the first element that is related to our preferred document 73 if ( a === document || a.ownerDocument === document && 74 jQuery.contains( document, a ) ) { 75 return -1; 76 } 77 if ( b === document || b.ownerDocument === document && 78 jQuery.contains( document, b ) ) { 79 return 1; 80 } 81 82 // Maintain original order 83 return sortInput ? 84 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 85 0; 86 } 87 88 return compare & 4 ? -1 : 1; 89 } 90 91 function uniqueSort( results ) { 92 var elem, 93 duplicates = [], 94 j = 0, 95 i = 0; 96 97 hasDuplicate = false; 98 sortInput = !sortStable && results.slice( 0 ); 99 results.sort( sortOrder ); 100 101 if ( hasDuplicate ) { 102 while ( ( elem = results[ i++ ] ) ) { 103 if ( elem === results[ i ] ) { 104 j = duplicates.push( i ); 105 } 106 } 107 while ( j-- ) { 108 results.splice( duplicates[ j ], 1 ); 109 } 110 } 111 112 // Clear input after sorting to release objects 113 // See https://github.com/jquery/sizzle/pull/225 114 sortInput = null; 115 116 return results; 117 } 118 119 jQuery.extend( { 120 121 // This method cannot be shared with the main selector module 122 // as it does in 4.x because of an edge case quirk of putting 123 // disconnected elements in the preferred document before other 124 // elements in the full selector module. This will be a minor 125 // breaking change in 4.0.0. 126 uniqueSort: uniqueSort, 127 unique: uniqueSort, 128 129 find: function( selector, context, results, seed ) { 130 var elem, nodeType, 131 i = 0; 132 133 results = results || []; 134 context = context || document; 135 136 // Same basic safeguard as in the full selector module 137 if ( !selector || typeof selector !== "string" ) { 138 return results; 139 } 140 141 // Early return if context is not an element, document or document fragment 142 if ( ( nodeType = context.nodeType ) !== 1 && nodeType !== 9 && nodeType !== 11 ) { 143 return []; 144 } 145 146 if ( seed ) { 147 while ( ( elem = seed[ i++ ] ) ) { 148 if ( jQuery.find.matchesSelector( elem, selector ) ) { 149 results.push( elem ); 150 } 151 } 152 } else { 153 jQuery.merge( results, context.querySelectorAll( selector ) ); 154 } 155 156 return results; 157 }, 158 expr: { 159 attrHandle: {}, 160 match: { 161 bool: new RegExp( "^(?:checked|selected|async|autofocus|autoplay|controls|defer" + 162 "|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped)$", "i" ), 163 needsContext: /^[\x20\t\r\n\f]*[>+~]/ 164 } 165 } 166 } ); 167 168 jQuery.fn.uniqueSort = function() { 169 return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); 170 }; 171 172 jQuery.extend( jQuery.find, { 173 matches: function( expr, elements ) { 174 return jQuery.find( expr, null, null, elements ); 175 }, 176 matchesSelector: function( elem, expr ) { 177 return matches.call( elem, expr ); 178 }, 179 attr: function( elem, name ) { 180 var fn = jQuery.expr.attrHandle[ name.toLowerCase() ], 181 182 // Don't get fooled by Object.prototype properties (jQuery trac-13807) 183 value = fn && hasOwn.call( jQuery.expr.attrHandle, name.toLowerCase() ) ? 184 fn( elem, name, jQuery.isXMLDoc( elem ) ) : 185 undefined; 186 return value !== undefined ? value : elem.getAttribute( name ); 187 } 188 } ); 189 190 } );