Separate jQuery.fn.init into its own module (for lighter core dependencies across all modules)

This commit is contained in:
Timmy Willison 2013-09-09 19:13:01 -05:00
parent d788010aa7
commit 825ac37736
18 changed files with 250 additions and 213 deletions

View File

@ -3,6 +3,7 @@ define([
"./var/rnotwhite",
"./ajax/var/nonce",
"./ajax/var/rquery",
"./core/init",
"./ajax/parseJSON",
"./ajax/parseXML",
"./deferred"

View File

@ -2,7 +2,8 @@ define([
"../core",
"../var/rnotwhite",
"../var/strundefined",
"../data/var/data_priv"
"../data/var/data_priv",
"../core/init"
], function( jQuery, rnotwhite, strundefined, data_priv ) {
var rclass = /[\t\r\n\f]/g;

View File

@ -1,6 +1,7 @@
define([
"../core",
"./support"
"./support",
"../core/init"
], function( jQuery, support ) {
var rreturn = /\r/g;

View File

@ -10,12 +10,8 @@ var
toString = require( "./var/toString" ),
hasOwn = require( "./var/hasOwn" ),
trim = require( "./var/trim" ),
rsingleTag = require( "./var/rsingleTag" ),
support = require( "./var/support" ),
// A central reference to the root jQuery(document)
rootjQuery,
// Use the correct document accordingly with window argument (sandbox)
document = window.document,
@ -30,14 +26,10 @@ 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 );
},
// A simple way to check for HTML strings
// Prioritize #id over <tag> 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,
@ -53,105 +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 ) {
// 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: "",
@ -231,9 +124,6 @@ jQuery.fn = jQuery.prototype = {
splice: arr.splice
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
@ -621,8 +511,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;
});

123
src/core/init.js Normal file
View File

@ -0,0 +1,123 @@
// Initialize a jQuery object
define([
"../core",
"./var/rsingleTag",
"../traversing/findFilter"
], function( jQuery, rsingleTag ) {
// A central reference to the root jQuery(document)
var rootjQuery,
// A simple way to check for HTML strings
// Prioritize #id over <tag> 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 ) {
// 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;
});

View File

@ -1,6 +1,6 @@
define([
"../core",
"../var/rsingleTag",
"./var/rsingleTag",
"../manipulation" // buildFragment
], function( jQuery, rsingleTag ) {

View File

@ -1,5 +1,6 @@
define([
"../core",
"../core/init",
"../deferred"
], function( jQuery ) {

View File

@ -29,6 +29,7 @@ var
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
// Dependencies not needed as vars
require( "./core/init" );
require( "./css/swap" );
require( "./core/ready" );
require( "./selector" ); // contains

1
src/effects.js vendored
View File

@ -63,6 +63,7 @@ var
};
// Dependencies not needed as vars
require( "./core/init" );
require( "./effects/Tween" );
require( "./queue" );
require( "./css" );

View File

@ -14,6 +14,7 @@ var
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
// Dependencies not needed as vars
require( "./core/init" );
require( "./data/accepts" );
require( "./selector" );

View File

@ -42,6 +42,7 @@ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.the
wrapMap.th = wrapMap.td;
// Dependencies not needed as variables
require( "./core/init" );
require( "./data/accepts" );
require( "./traversing" );
require( "./selector" );

View File

@ -2,6 +2,7 @@ define([
"./core",
"./var/strundefined",
"./core/access",
"./core/init",
"./css",
"./selector" // contains
], function( jQuery, strundefined, access ) {

View File

@ -1,6 +1,7 @@
define([
"./core",
"./manipulation/var/rcheckableType",
"./core/init",
"./traversing", // filter
"./attributes/prop"
], function( jQuery, rcheckableType ) {

View File

@ -1,12 +1,13 @@
define([
"./core",
"./var/indexOf",
"./traversing/var/rneedsContext",
"./core/init",
"./traversing/findFilter",
"./selector"
], function( jQuery, indexOf ) {
], function( jQuery, indexOf, 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,
@ -15,51 +16,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 ( indexOf.call( qualifier, elem ) >= 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 = [],
truncate = until !== undefined;
@ -89,32 +46,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 targets = jQuery( target, this ),
l = targets.length;
@ -129,27 +60,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,

View File

@ -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 ( indexOf.call( qualifier, elem ) >= 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;
}
});
});

View File

@ -0,0 +1,6 @@
define([
"../../core",
"../../selector"
], function( jQuery ) {
return jQuery.expr.match.needsContext;
});

View File

@ -1,5 +1,6 @@
define([
"./core",
"./core/init",
"./traversing" // parent, contents
], function( jQuery ) {