selector-native.js 5.0 KB

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