selector-native.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. define( [
  2. "./core",
  3. "./var/document",
  4. "./var/documentElement",
  5. "./var/hasOwn",
  6. "./var/indexOf"
  7. ], function( jQuery, document, documentElement, hasOwn, indexOf ) {
  8. "use strict";
  9. /*
  10. * Optional (non-Sizzle) selector module for custom builds.
  11. *
  12. * Note that this DOES NOT SUPPORT many documented jQuery
  13. * features in exchange for its smaller size:
  14. *
  15. * Attribute not equal selector
  16. * Positional selectors (:first; :eq(n); :odd; etc.)
  17. * Type selectors (:input; :checkbox; :button; etc.)
  18. * State-based selectors (:animated; :visible; :hidden; etc.)
  19. * :has(selector)
  20. * :not(complex selector)
  21. * custom selectors via Sizzle extensions
  22. * Leading combinators (e.g., $collection.find("> *"))
  23. * Reliable functionality on XML fragments
  24. * Requiring all parts of a selector to match elements under context
  25. * (e.g., $div.find("div > *") now matches children of $div)
  26. * Matching against non-elements
  27. * Reliable sorting of disconnected nodes
  28. * querySelectorAll bug fixes (e.g., unreliable :focus on WebKit)
  29. *
  30. * If any of these are unacceptable tradeoffs, either use Sizzle or
  31. * customize this stub for the project's specific needs.
  32. */
  33. var hasDuplicate, sortInput,
  34. sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando,
  35. matches = documentElement.matches ||
  36. documentElement.webkitMatchesSelector ||
  37. documentElement.mozMatchesSelector ||
  38. documentElement.oMatchesSelector ||
  39. documentElement.msMatchesSelector,
  40. // CSS string/identifier serialization
  41. // https://drafts.csswg.org/cssom/#common-serializing-idioms
  42. rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,
  43. fcssescape = function( ch, asCodePoint ) {
  44. if ( asCodePoint ) {
  45. // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
  46. if ( ch === "\0" ) {
  47. return "\uFFFD";
  48. }
  49. // Control characters and (dependent upon position) numbers get escaped as code points
  50. return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
  51. }
  52. // Other potentially-special ASCII characters get backslash-escaped
  53. return "\\" + ch;
  54. };
  55. function sortOrder( a, b ) {
  56. // Flag for duplicate removal
  57. if ( a === b ) {
  58. hasDuplicate = true;
  59. return 0;
  60. }
  61. // Sort on method existence if only one input has compareDocumentPosition
  62. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  63. if ( compare ) {
  64. return compare;
  65. }
  66. // Calculate position if both inputs belong to the same document
  67. compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  68. a.compareDocumentPosition( b ) :
  69. // Otherwise we know they are disconnected
  70. 1;
  71. // Disconnected nodes
  72. if ( compare & 1 ) {
  73. // Choose the first element that is related to our preferred document
  74. if ( a === document || a.ownerDocument === document &&
  75. jQuery.contains( document, a ) ) {
  76. return -1;
  77. }
  78. if ( b === document || b.ownerDocument === document &&
  79. jQuery.contains( document, b ) ) {
  80. return 1;
  81. }
  82. // Maintain original order
  83. return sortInput ?
  84. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  85. 0;
  86. }
  87. return compare & 4 ? -1 : 1;
  88. }
  89. function uniqueSort( results ) {
  90. var elem,
  91. duplicates = [],
  92. j = 0,
  93. i = 0;
  94. hasDuplicate = false;
  95. sortInput = !sortStable && results.slice( 0 );
  96. results.sort( sortOrder );
  97. if ( hasDuplicate ) {
  98. while ( ( elem = results[ i++ ] ) ) {
  99. if ( elem === results[ i ] ) {
  100. j = duplicates.push( i );
  101. }
  102. }
  103. while ( j-- ) {
  104. results.splice( duplicates[ j ], 1 );
  105. }
  106. }
  107. // Clear input after sorting to release objects
  108. // See https://github.com/jquery/sizzle/pull/225
  109. sortInput = null;
  110. return results;
  111. }
  112. function escape( sel ) {
  113. return ( sel + "" ).replace( rcssescape, fcssescape );
  114. }
  115. jQuery.extend( {
  116. uniqueSort: uniqueSort,
  117. unique: uniqueSort,
  118. escapeSelector: escape,
  119. find: function( selector, context, results, seed ) {
  120. var elem, nodeType,
  121. i = 0;
  122. results = results || [];
  123. context = context || document;
  124. // Same basic safeguard as Sizzle
  125. if ( !selector || typeof selector !== "string" ) {
  126. return results;
  127. }
  128. // Early return if context is not an element or document
  129. if ( ( nodeType = context.nodeType ) !== 1 && nodeType !== 9 ) {
  130. return [];
  131. }
  132. if ( seed ) {
  133. while ( ( elem = seed[ i++ ] ) ) {
  134. if ( jQuery.find.matchesSelector( elem, selector ) ) {
  135. results.push( elem );
  136. }
  137. }
  138. } else {
  139. jQuery.merge( results, context.querySelectorAll( selector ) );
  140. }
  141. return results;
  142. },
  143. text: function( elem ) {
  144. var node,
  145. ret = "",
  146. i = 0,
  147. nodeType = elem.nodeType;
  148. if ( !nodeType ) {
  149. // If no nodeType, this is expected to be an array
  150. while ( ( node = elem[ i++ ] ) ) {
  151. // Do not traverse comment nodes
  152. ret += jQuery.text( node );
  153. }
  154. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  155. // Use textContent for elements
  156. return elem.textContent;
  157. } else if ( nodeType === 3 || nodeType === 4 ) {
  158. return elem.nodeValue;
  159. }
  160. // Do not include comment or processing instruction nodes
  161. return ret;
  162. },
  163. contains: function( a, b ) {
  164. var adown = a.nodeType === 9 ? a.documentElement : a,
  165. bup = b && b.parentNode;
  166. return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) );
  167. },
  168. isXMLDoc: function( elem ) {
  169. // documentElement is verified for cases where it doesn't yet exist
  170. // (such as loading iframes in IE - #4833)
  171. var documentElement = elem && ( elem.ownerDocument || elem ).documentElement;
  172. return documentElement ? documentElement.nodeName !== "HTML" : false;
  173. },
  174. expr: {
  175. attrHandle: {},
  176. match: {
  177. bool: new RegExp( "^(?:checked|selected|async|autofocus|autoplay|controls|defer" +
  178. "|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped)$", "i" ),
  179. needsContext: /^[\x20\t\r\n\f]*[>+~]/
  180. }
  181. }
  182. } );
  183. jQuery.extend( jQuery.find, {
  184. matches: function( expr, elements ) {
  185. return jQuery.find( expr, null, null, elements );
  186. },
  187. matchesSelector: function( elem, expr ) {
  188. return matches.call( elem, expr );
  189. },
  190. attr: function( elem, name ) {
  191. var fn = jQuery.expr.attrHandle[ name.toLowerCase() ],
  192. // Don't get fooled by Object.prototype properties (jQuery #13807)
  193. value = fn && hasOwn.call( jQuery.expr.attrHandle, name.toLowerCase() ) ?
  194. fn( elem, name, jQuery.isXMLDoc( elem ) ) :
  195. undefined;
  196. return value !== undefined ? value : elem.getAttribute( name );
  197. }
  198. } );
  199. } );