traversing.js 4.0 KB

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