From 2f627494f28c08e5bba3c32d6c9d9167503322fc Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Mon, 9 Sep 2013 19:13:01 -0500 Subject: [PATCH] Separate jQuery.fn.init into its own module (for lighter core dependencies across all modules). Restore proper support property for effects. Conflicts: src/attributes/classes.js src/core.js src/manipulation.js src/traversing.js --- src/ajax.js | 1 + src/attributes/classes.js | 3 +- src/attributes/val.js | 3 +- src/core.js | 229 ++++++---------------------- src/core/init.js | 132 ++++++++++++++++ src/core/parseHTML.js | 2 +- src/core/ready.js | 1 + src/{ => core}/var/rsingleTag.js | 0 src/css.js | 1 + src/effects.js | 3 +- src/event.js | 1 + src/manipulation.js | 12 +- src/offset.js | 1 + src/serialize.js | 1 + src/support.js | 9 ++ src/traversing.js | 100 +----------- src/traversing/findFilter.js | 100 ++++++++++++ src/traversing/var/rneedsContext.js | 6 + src/wrap.js | 1 + 19 files changed, 319 insertions(+), 287 deletions(-) create mode 100644 src/core/init.js rename src/{ => core}/var/rsingleTag.js (100%) create mode 100644 src/traversing/findFilter.js create mode 100644 src/traversing/var/rneedsContext.js diff --git a/src/ajax.js b/src/ajax.js index 41faad8af..9d9c36b8c 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -3,6 +3,7 @@ define([ "./var/rnotwhite", "./ajax/var/nonce", "./ajax/var/rquery", + "./core/init", "./ajax/parseJSON", "./ajax/parseXML", "./deferred" diff --git a/src/attributes/classes.js b/src/attributes/classes.js index 6ac81392d..64bc747c5 100644 --- a/src/attributes/classes.js +++ b/src/attributes/classes.js @@ -1,7 +1,8 @@ define([ "../core", "../var/rnotwhite", - "../var/strundefined" + "../var/strundefined", + "../core/init" ], function( jQuery, rnotwhite, strundefined ) { var rclass = /[\t\r\n\f]/g; diff --git a/src/attributes/val.js b/src/attributes/val.js index e25249fb1..1b5e86e1e 100644 --- a/src/attributes/val.js +++ b/src/attributes/val.js @@ -1,6 +1,7 @@ define([ "../core", - "./support" + "./support", + "../core/init" ], function( jQuery, support ) { var rreturn = /\r/g; diff --git a/src/core.js b/src/core.js index 01b3d9a92..7e190a480 100644 --- a/src/core.js +++ b/src/core.js @@ -10,17 +10,8 @@ var toString = require( "./var/toString" ), hasOwn = require( "./var/hasOwn" ), trim = require( "./var/trim" ), - rsingleTag = require( "./var/rsingleTag" ), support = require( "./var/support" ), - i, - - // A central reference to the root jQuery(document) - rootjQuery, - - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - // Map over jQuery in case of overwrite _jQuery = window.jQuery, @@ -32,17 +23,13 @@ var // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); }, // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, @@ -58,111 +45,6 @@ jQuery.fn = jQuery.prototype = { constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - // Start with an empty selector selector: "", @@ -242,9 +124,6 @@ jQuery.fn = jQuery.prototype = { splice: deletedIds.splice }; -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, @@ -348,6 +227,51 @@ jQuery.extend({ return !isNaN( parseFloat(obj) ) && isFinite( obj ); }, + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + type: function( obj ) { if ( obj == null ) { return String( obj ); @@ -357,14 +281,6 @@ jQuery.extend({ typeof obj; }, - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - error: function( msg ) { throw new Error( msg ); }, @@ -615,54 +531,6 @@ jQuery.extend({ support: support }); - -// Support: IE<9 -// Iteration over object's inherited properties before its own. -// It would be better to move this test to one of test modules but since -// tests require the jQuery object to exist as well as some other variables set -// core initialization is needed first for tests used in core itself. -for ( i in jQuery( support ) ) { - break; -} -support.ownLast = i !== "0"; - -jQuery.isPlainObject = function( obj ) { - var key; - - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( support.ownLast ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); -}; - // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); @@ -685,8 +553,5 @@ function isArraylike( obj ) { typeof length === "number" && length > 0 && ( length - 1 ) in obj ); } -// All jQuery objects should point back to these -rootjQuery = jQuery( document ); - return jQuery; }); diff --git a/src/core/init.js b/src/core/init.js new file mode 100644 index 000000000..f2db547a9 --- /dev/null +++ b/src/core/init.js @@ -0,0 +1,132 @@ +// Initialize a jQuery object +define([ + "../core", + "./var/rsingleTag", + "../traversing/findFilter" +], function( jQuery, rsingleTag ) { + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + +return init; + +}); diff --git a/src/core/parseHTML.js b/src/core/parseHTML.js index 15e3e512f..64cf2a18a 100644 --- a/src/core/parseHTML.js +++ b/src/core/parseHTML.js @@ -1,6 +1,6 @@ define([ "../core", - "../var/rsingleTag", + "./var/rsingleTag", "../manipulation" // buildFragment ], function( jQuery, rsingleTag ) { diff --git a/src/core/ready.js b/src/core/ready.js index 8e01c260d..87be24155 100644 --- a/src/core/ready.js +++ b/src/core/ready.js @@ -1,5 +1,6 @@ define([ "../core", + "../core/init", "../deferred" ], function( jQuery ) { diff --git a/src/var/rsingleTag.js b/src/core/var/rsingleTag.js similarity index 100% rename from src/var/rsingleTag.js rename to src/core/var/rsingleTag.js diff --git a/src/css.js b/src/css.js index b62f67112..a7c9e1c6f 100644 --- a/src/css.js +++ b/src/css.js @@ -33,6 +33,7 @@ var cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; // Dependencies not needed as vars +require( "./core/init" ); require( "./css/swap" ); require( "./core/ready" ); require( "./selector" ); // contains diff --git a/src/effects.js b/src/effects.js index caed88ea7..d5baaca99 100644 --- a/src/effects.js +++ b/src/effects.js @@ -6,7 +6,7 @@ var cssExpand = require( "./css/var/cssExpand" ), isHidden = require( "./css/var/isHidden" ), defaultDisplay = require( "./css/defaultDisplay" ), - support = require( "./css/support" ), + support = require( "./effects/support" ), fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, @@ -65,6 +65,7 @@ var }; // Dependencies not needed as vars +require( "./core/init" ); require( "./effects/Tween" ); require( "./queue" ); require( "./css" ); diff --git a/src/event.js b/src/event.js index 7523c1db7..12ad019c2 100644 --- a/src/event.js +++ b/src/event.js @@ -14,6 +14,7 @@ var rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; // Dependencies not needed as vars +require( "./core/init" ); require( "./data/accepts" ); require( "./selector" ); diff --git a/src/manipulation.js b/src/manipulation.js index a52040e45..0094b279a 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -2,12 +2,6 @@ // Keep in mind that a dependency array cannot be used with CommonJS+AMD syntax define(function( require ){ -// Dependencies not needed as variables -require( "./data/accepts" ); -require( "./traversing" ); -require( "./selector" ); -require( "./event" ); - function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); @@ -71,6 +65,12 @@ wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; +// Dependencies not needed as variables +require( "./core/init" ); +require( "./data/accepts" ); +require( "./traversing" ); +require( "./selector" ); +require( "./event" ); function getAll( context, tag ) { var elems, elem, diff --git a/src/offset.js b/src/offset.js index ff7c867cb..cfc260da2 100644 --- a/src/offset.js +++ b/src/offset.js @@ -2,6 +2,7 @@ define([ "./core", "./var/strundefined", "./core/access", + "./core/init", "./css", "./selector" // contains ], function( jQuery, strundefined, access ) { diff --git a/src/serialize.js b/src/serialize.js index 85798ef62..797d735aa 100644 --- a/src/serialize.js +++ b/src/serialize.js @@ -1,6 +1,7 @@ define([ "./core", "./manipulation/var/rcheckableType", + "./core/init", "./traversing", // filter "./attributes/prop" ], function( jQuery, rcheckableType ) { diff --git a/src/support.js b/src/support.js index 832f192d5..e039a7a4f 100644 --- a/src/support.js +++ b/src/support.js @@ -2,10 +2,19 @@ define([ "./core", "./var/strundefined", "./var/support", + "./core/init", // Needed for hasOwn support test // This is listed as a dependency for build order, but it's still optional in builds "./core/ready" ], function( jQuery, strundefined, support ) { +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + // Note: most support tests are defined in their respective modules. jQuery(function() { diff --git a/src/traversing.js b/src/traversing.js index 4f3bba0fc..02ea249fe 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -1,11 +1,12 @@ define([ "./core", + "./traversing/var/rneedsContext", + "./core/init", + "./traversing/findFilter", "./selector" -], function( jQuery ) { +], function( jQuery, rneedsContext ) { -var isSimple = /^.[^:#\[\.,]*$/, - rparentsprev = /^(?:parents|prev(?:Until|All))/, - rneedsContext = jQuery.expr.match.needsContext, +var rparentsprev = /^(?:parents|prev(?:Until|All))/, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, @@ -14,51 +15,7 @@ var isSimple = /^.[^:#\[\.,]*$/, prev: true }; -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( isSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; - }); -} - jQuery.extend({ - filter: function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); - }, - dir: function( elem, dir, until ) { var matched = [], cur = elem[ dir ]; @@ -86,32 +43,6 @@ jQuery.extend({ }); jQuery.fn.extend({ - find: function( selector ) { - var i, - ret = [], - self = this, - len = self.length; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - has: function( target ) { var i, targets = jQuery( target, this ), @@ -126,27 +57,6 @@ jQuery.fn.extend({ }); }, - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - }, - closest: function( selectors, context ) { var cur, i = 0, diff --git a/src/traversing/findFilter.js b/src/traversing/findFilter.js new file mode 100644 index 000000000..e295045a5 --- /dev/null +++ b/src/traversing/findFilter.js @@ -0,0 +1,100 @@ +define([ + "../core", + "../var/indexOf", + "./var/rneedsContext", + "../selector" +], function( jQuery, indexOf, rneedsContext ) { + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + +}); diff --git a/src/traversing/var/rneedsContext.js b/src/traversing/var/rneedsContext.js new file mode 100644 index 000000000..3d6ae4038 --- /dev/null +++ b/src/traversing/var/rneedsContext.js @@ -0,0 +1,6 @@ +define([ + "../../core", + "../../selector" +], function( jQuery ) { + return jQuery.expr.match.needsContext; +}); diff --git a/src/wrap.js b/src/wrap.js index 1ec2771ce..a3c35d9f2 100644 --- a/src/wrap.js +++ b/src/wrap.js @@ -1,5 +1,6 @@ define([ "./core", + "./core/init", "./traversing" // parent, contents ], function( jQuery ) { -- 2.39.5