selector-native.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. rhtmlSuffix = /HTML$/i,
  35. sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando,
  36. matches = documentElement.matches ||
  37. documentElement.webkitMatchesSelector ||
  38. documentElement.mozMatchesSelector ||
  39. documentElement.oMatchesSelector ||
  40. documentElement.msMatchesSelector,
  41. // CSS string/identifier serialization
  42. // https://drafts.csswg.org/cssom/#common-serializing-idioms
  43. rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,
  44. fcssescape = function( ch, asCodePoint ) {
  45. if ( asCodePoint ) {
  46. // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
  47. if ( ch === "\0" ) {
  48. return "\uFFFD";
  49. }
  50. // Control characters and (dependent upon position) numbers get escaped as code points
  51. return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
  52. }
  53. // Other potentially-special ASCII characters get backslash-escaped
  54. return "\\" + ch;
  55. };
  56. function sortOrder( a, b ) {
  57. // Flag for duplicate removal
  58. if ( a === b ) {
  59. hasDuplicate = true;
  60. return 0;
  61. }
  62. // Sort on method existence if only one input has compareDocumentPosition
  63. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  64. if ( compare ) {
  65. return compare;
  66. }
  67. // Calculate position if both inputs belong to the same document
  68. compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  69. a.compareDocumentPosition( b ) :
  70. // Otherwise we know they are disconnected
  71. 1;
  72. // Disconnected nodes
  73. if ( compare & 1 ) {
  74. // Choose the first element that is related to our preferred document
  75. if ( a === document || a.ownerDocument === document &&
  76. jQuery.contains( document, a ) ) {
  77. return -1;
  78. }
  79. if ( b === document || b.ownerDocument === document &&
  80. jQuery.contains( document, b ) ) {
  81. return 1;
  82. }
  83. // Maintain original order
  84. return sortInput ?
  85. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  86. 0;
  87. }
  88. return compare & 4 ? -1 : 1;
  89. }
  90. function uniqueSort( results ) {
  91. var elem,
  92. duplicates = [],
  93. j = 0,
  94. i = 0;
  95. hasDuplicate = false;
  96. sortInput = !sortStable && results.slice( 0 );
  97. results.sort( sortOrder );
  98. if ( hasDuplicate ) {
  99. while ( ( elem = results[ i++ ] ) ) {
  100. if ( elem === results[ i ] ) {
  101. j = duplicates.push( i );
  102. }
  103. }
  104. while ( j-- ) {
  105. results.splice( duplicates[ j ], 1 );
  106. }
  107. }
  108. // Clear input after sorting to release objects
  109. // See https://github.com/jquery/sizzle/pull/225
  110. sortInput = null;
  111. return results;
  112. }
  113. function escape( sel ) {
  114. return ( sel + "" ).replace( rcssescape, fcssescape );
  115. }
  116. jQuery.extend( {
  117. uniqueSort: uniqueSort,
  118. unique: uniqueSort,
  119. escapeSelector: escape,
  120. find: function( selector, context, results, seed ) {
  121. var elem, nodeType,
  122. i = 0;
  123. results = results || [];
  124. context = context || document;
  125. // Same basic safeguard as Sizzle
  126. if ( !selector || typeof selector !== "string" ) {
  127. return results;
  128. }
  129. // Early return if context is not an element or document
  130. if ( ( nodeType = context.nodeType ) !== 1 && nodeType !== 9 ) {
  131. return [];
  132. }
  133. if ( seed ) {
  134. while ( ( elem = seed[ i++ ] ) ) {
  135. if ( jQuery.find.matchesSelector( elem, selector ) ) {
  136. results.push( elem );
  137. }
  138. }
  139. } else {
  140. jQuery.merge( results, context.querySelectorAll( selector ) );
  141. }
  142. return results;
  143. },
  144. text: function( elem ) {
  145. var node,
  146. ret = "",
  147. i = 0,
  148. nodeType = elem.nodeType;
  149. if ( !nodeType ) {
  150. // If no nodeType, this is expected to be an array
  151. while ( ( node = elem[ i++ ] ) ) {
  152. // Do not traverse comment nodes
  153. ret += jQuery.text( node );
  154. }
  155. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  156. // Use textContent for elements
  157. return elem.textContent;
  158. } else if ( nodeType === 3 || nodeType === 4 ) {
  159. return elem.nodeValue;
  160. }
  161. // Do not include comment or processing instruction nodes
  162. return ret;
  163. },
  164. contains: function( a, b ) {
  165. var adown = a.nodeType === 9 ? a.documentElement : a,
  166. bup = b && b.parentNode;
  167. return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) );
  168. },
  169. isXMLDoc: function( elem ) {
  170. var namespace = elem.namespaceURI,
  171. documentElement = ( elem.ownerDocument || elem ).documentElement;
  172. // Assume HTML when documentElement doesn't yet exist, such as inside
  173. // document fragments.
  174. return !rhtmlSuffix.test( namespace ||
  175. documentElement && documentElement.nodeName ||
  176. "HTML" );
  177. },
  178. expr: {
  179. attrHandle: {},
  180. match: {
  181. bool: new RegExp( "^(?:checked|selected|async|autofocus|autoplay|controls|defer" +
  182. "|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped)$", "i" ),
  183. needsContext: /^[\x20\t\r\n\f]*[>+~]/
  184. }
  185. }
  186. } );
  187. jQuery.extend( jQuery.find, {
  188. matches: function( expr, elements ) {
  189. return jQuery.find( expr, null, null, elements );
  190. },
  191. matchesSelector: function( elem, expr ) {
  192. return matches.call( elem, expr );
  193. },
  194. attr: function( elem, name ) {
  195. var fn = jQuery.expr.attrHandle[ name.toLowerCase() ],
  196. // Don't get fooled by Object.prototype properties (jQuery #13807)
  197. value = fn && hasOwn.call( jQuery.expr.attrHandle, name.toLowerCase() ) ?
  198. fn( elem, name, jQuery.isXMLDoc( elem ) ) :
  199. undefined;
  200. return value !== undefined ? value : elem.getAttribute( name );
  201. }
  202. } );
  203. } );