traversing.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. define( [
  2. "./core",
  3. "./var/indexOf",
  4. "./traversing/var/dir",
  5. "./traversing/var/siblings",
  6. "./traversing/var/rneedsContext",
  7. "./core/init",
  8. "./traversing/findFilter",
  9. "./selector"
  10. ], function( jQuery, indexOf, dir, siblings, rneedsContext ) {
  11. "use strict";
  12. var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  13. // Methods guaranteed to produce a unique set when starting from a unique set
  14. guaranteedUnique = {
  15. children: true,
  16. contents: true,
  17. next: true,
  18. prev: true
  19. };
  20. jQuery.fn.extend( {
  21. has: function( target ) {
  22. var targets = jQuery( target, this ),
  23. l = targets.length;
  24. return this.filter( function() {
  25. var i = 0;
  26. for ( ; i < l; i++ ) {
  27. if ( jQuery.contains( this, targets[ i ] ) ) {
  28. return true;
  29. }
  30. }
  31. } );
  32. },
  33. closest: function( selectors, context ) {
  34. var cur,
  35. i = 0,
  36. l = this.length,
  37. matched = [],
  38. targets = typeof selectors !== "string" && jQuery( selectors );
  39. // Positional selectors never match, since there's no _selection_ context
  40. if ( !rneedsContext.test( selectors ) ) {
  41. for ( ; i < l; i++ ) {
  42. for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
  43. // Always skip document fragments
  44. if ( cur.nodeType < 11 && ( targets ?
  45. targets.index( cur ) > -1 :
  46. // Don't pass non-elements to Sizzle
  47. cur.nodeType === 1 &&
  48. jQuery.find.matchesSelector( cur, selectors ) ) ) {
  49. matched.push( cur );
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
  56. },
  57. // Determine the position of an element within the set
  58. index: function( elem ) {
  59. // No argument, return index in parent
  60. if ( !elem ) {
  61. return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  62. }
  63. // Index in selector
  64. if ( typeof elem === "string" ) {
  65. return indexOf.call( jQuery( elem ), this[ 0 ] );
  66. }
  67. // Locate the position of the desired element
  68. return indexOf.call( this,
  69. // If it receives a jQuery object, the first element is used
  70. elem.jquery ? elem[ 0 ] : elem
  71. );
  72. },
  73. add: function( selector, context ) {
  74. return this.pushStack(
  75. jQuery.uniqueSort(
  76. jQuery.merge( this.get(), jQuery( selector, context ) )
  77. )
  78. );
  79. },
  80. addBack: function( selector ) {
  81. return this.add( selector == null ?
  82. this.prevObject : this.prevObject.filter( selector )
  83. );
  84. }
  85. } );
  86. function sibling( cur, dir ) {
  87. while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
  88. return cur;
  89. }
  90. jQuery.each( {
  91. parent: function( elem ) {
  92. var parent = elem.parentNode;
  93. return parent && parent.nodeType !== 11 ? parent : null;
  94. },
  95. parents: function( elem ) {
  96. return dir( elem, "parentNode" );
  97. },
  98. parentsUntil: function( elem, i, until ) {
  99. return dir( elem, "parentNode", until );
  100. },
  101. next: function( elem ) {
  102. return sibling( elem, "nextSibling" );
  103. },
  104. prev: function( elem ) {
  105. return sibling( elem, "previousSibling" );
  106. },
  107. nextAll: function( elem ) {
  108. return dir( elem, "nextSibling" );
  109. },
  110. prevAll: function( elem ) {
  111. return dir( elem, "previousSibling" );
  112. },
  113. nextUntil: function( elem, i, until ) {
  114. return dir( elem, "nextSibling", until );
  115. },
  116. prevUntil: function( elem, i, until ) {
  117. return dir( elem, "previousSibling", until );
  118. },
  119. siblings: function( elem ) {
  120. return siblings( ( elem.parentNode || {} ).firstChild, elem );
  121. },
  122. children: function( elem ) {
  123. return siblings( elem.firstChild );
  124. },
  125. contents: function( elem ) {
  126. return elem.contentDocument || jQuery.merge( [], elem.childNodes );
  127. }
  128. }, function( name, fn ) {
  129. jQuery.fn[ name ] = function( until, selector ) {
  130. var matched = jQuery.map( this, fn, until );
  131. if ( name.slice( -5 ) !== "Until" ) {
  132. selector = until;
  133. }
  134. if ( selector && typeof selector === "string" ) {
  135. matched = jQuery.filter( selector, matched );
  136. }
  137. if ( this.length > 1 ) {
  138. // Remove duplicates
  139. if ( !guaranteedUnique[ name ] ) {
  140. jQuery.uniqueSort( matched );
  141. }
  142. // Reverse order for parents* and prev-derivatives
  143. if ( rparentsprev.test( name ) ) {
  144. matched.reverse();
  145. }
  146. }
  147. return this.pushStack( matched );
  148. };
  149. } );
  150. return jQuery;
  151. } );