mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Fix #13434: native-API selector module
What's out: * 6 KB * attribute not equal selector * positional selectors (:first; :eq(n); :odd; etc.) * type selectors (:input; :checkbox; :button; etc.) * state-based selectors (:animated; :visible; :hidden; etc.) * :has(selector) * custom selectors * leading combinators (e.g., $collection.find("> *")) * reliable functionality on XML fragments * requiring all parts of a selector to match elements under context (e.g., $div.find("div > *") now matches children of $div) * matching against non-elements * reliable sorting of disconnected nodes
This commit is contained in:
parent
0618710913
commit
1083f82d1e
44
Gruntfile.js
44
Gruntfile.js
@ -22,7 +22,7 @@ module.exports = function( grunt ) {
|
|||||||
files: distpaths
|
files: distpaths
|
||||||
},
|
},
|
||||||
selector: {
|
selector: {
|
||||||
destFile: "src/selector.js",
|
destFile: "src/selector-sizzle.js",
|
||||||
apiFile: "src/sizzle-jquery.js",
|
apiFile: "src/sizzle-jquery.js",
|
||||||
srcFile: "src/sizzle/sizzle.js"
|
srcFile: "src/sizzle/sizzle.js"
|
||||||
},
|
},
|
||||||
@ -39,10 +39,9 @@ module.exports = function( grunt ) {
|
|||||||
"src/queue.js",
|
"src/queue.js",
|
||||||
"src/attributes.js",
|
"src/attributes.js",
|
||||||
"src/event.js",
|
"src/event.js",
|
||||||
"src/selector.js",
|
{ flag: "sizzle", src: "src/selector-sizzle.js", alt: "src/selector-native.js" },
|
||||||
"src/traversing.js",
|
"src/traversing.js",
|
||||||
"src/manipulation.js",
|
"src/manipulation.js",
|
||||||
|
|
||||||
{ flag: "css", src: "src/css.js" },
|
{ flag: "css", src: "src/css.js" },
|
||||||
"src/serialize.js",
|
"src/serialize.js",
|
||||||
{ flag: "event-alias", src: "src/event-alias.js" },
|
{ flag: "event-alias", src: "src/event-alias.js" },
|
||||||
@ -145,8 +144,7 @@ module.exports = function( grunt ) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build src/selector.js
|
grunt.registerTask( "selector", "Build Sizzle-based selector module", function() {
|
||||||
grunt.registerTask( "selector", "Build src/selector.js", function() {
|
|
||||||
|
|
||||||
var cfg = grunt.config("selector"),
|
var cfg = grunt.config("selector"),
|
||||||
name = cfg.destFile,
|
name = cfg.destFile,
|
||||||
@ -190,7 +188,7 @@ module.exports = function( grunt ) {
|
|||||||
// Rejoin the pieces
|
// Rejoin the pieces
|
||||||
compiled = parts.join("");
|
compiled = parts.join("");
|
||||||
|
|
||||||
grunt.verbose.write("Injected sizzle-jquery.js into sizzle.js");
|
grunt.verbose.writeln("Injected " + cfg.apiFile + " into " + cfg.srcFile);
|
||||||
|
|
||||||
// Write concatenated source to file, and ensure newline-only termination
|
// Write concatenated source to file, and ensure newline-only termination
|
||||||
grunt.file.write( name, compiled.replace( /\x0d\x0a/g, "\x0a" ) );
|
grunt.file.write( name, compiled.replace( /\x0d\x0a/g, "\x0a" ) );
|
||||||
@ -328,37 +326,47 @@ module.exports = function( grunt ) {
|
|||||||
var flag = filepath.flag,
|
var flag = filepath.flag,
|
||||||
specified = false,
|
specified = false,
|
||||||
omit = false,
|
omit = false,
|
||||||
message = "";
|
messages = [];
|
||||||
|
|
||||||
if ( flag ) {
|
if ( flag ) {
|
||||||
if ( excluded[ flag ] !== undefined ) {
|
if ( excluded[ flag ] !== undefined ) {
|
||||||
message = ( "Excluding " + flag ).red;
|
messages.push([
|
||||||
|
( "Excluding " + flag ).red,
|
||||||
|
( "(" + filepath.src + ")" ).grey
|
||||||
|
]);
|
||||||
specified = true;
|
specified = true;
|
||||||
omit = true;
|
omit = !filepath.alt;
|
||||||
} else {
|
if ( !omit ) {
|
||||||
message = ( "Including " + flag ).green;
|
flag += " alternate";
|
||||||
|
filepath.src = filepath.alt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( excluded[ flag ] === undefined ) {
|
||||||
|
messages.push([
|
||||||
|
( "Including " + flag ).green,
|
||||||
|
( "(" + filepath.src + ")" ).grey
|
||||||
|
]);
|
||||||
|
|
||||||
// If this module was actually specified by the
|
// If this module was actually specified by the
|
||||||
// builder, then st the flag to include it in the
|
// builder, then set the flag to include it in the
|
||||||
// output list
|
// output list
|
||||||
if ( modules[ "+" + flag ] ) {
|
if ( modules[ "+" + flag ] ) {
|
||||||
specified = true;
|
specified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filepath = filepath.src;
|
||||||
|
|
||||||
// Only display the inclusion/exclusion list when handling
|
// Only display the inclusion/exclusion list when handling
|
||||||
// an explicit list.
|
// an explicit list.
|
||||||
//
|
//
|
||||||
// Additionally, only display modules that have been specified
|
// Additionally, only display modules that have been specified
|
||||||
// by the user
|
// by the user
|
||||||
if ( explicit && specified ) {
|
if ( explicit && specified ) {
|
||||||
grunt.log.writetableln([ 27, 30 ], [
|
messages.forEach(function( message ) {
|
||||||
message,
|
grunt.log.writetableln( [ 27, 30 ], message );
|
||||||
( "(" + filepath.src + ")").grey
|
});
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filepath = filepath.src;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !omit ) {
|
if ( !omit ) {
|
||||||
|
125
src/selector-native.js
Normal file
125
src/selector-native.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
var selector_hasDuplicate,
|
||||||
|
matches = docElem.matchesSelector ||
|
||||||
|
docElem.mozMatchesSelector ||
|
||||||
|
docElem.webkitMatchesSelector ||
|
||||||
|
docElem.oMatchesSelector ||
|
||||||
|
docElem.msMatchesSelector,
|
||||||
|
selector_sortOrder = function( a, b ) {
|
||||||
|
// Flag for duplicate removal
|
||||||
|
if ( a === b ) {
|
||||||
|
selector_hasDuplicate = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
|
||||||
|
|
||||||
|
if ( compare ) {
|
||||||
|
// Disconnected nodes
|
||||||
|
if ( compare & 1 ) {
|
||||||
|
|
||||||
|
// Choose the first element that is related to our document
|
||||||
|
if ( a === document || jQuery.contains(document, a) ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( b === document || jQuery.contains(document, b) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maintain original order
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return compare & 4 ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not directly comparable, sort on existence of method
|
||||||
|
return a.compareDocumentPosition ? -1 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.extend({
|
||||||
|
find: function( selector, context, results, seed ) {
|
||||||
|
var elem,
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
results = results || [];
|
||||||
|
context = context || document;
|
||||||
|
|
||||||
|
if ( seed ) {
|
||||||
|
while ( (elem = seed[i++]) ) {
|
||||||
|
if ( jQuery.find.matchesSelector(elem, selector) ) {
|
||||||
|
results.push( elem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jQuery.merge( results, context.querySelectorAll(selector) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
unique: function( results ) {
|
||||||
|
var elem,
|
||||||
|
duplicates = [],
|
||||||
|
i = 0,
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
selector_hasDuplicate = false;
|
||||||
|
results.sort( selector_sortOrder );
|
||||||
|
|
||||||
|
if ( selector_hasDuplicate ) {
|
||||||
|
while ( (elem = results[i++]) ) {
|
||||||
|
if ( elem === results[ i ] ) {
|
||||||
|
j = duplicates.push( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( j-- ) {
|
||||||
|
results.splice( duplicates[ j ], 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
text: function( elem ) {
|
||||||
|
var node,
|
||||||
|
ret = "",
|
||||||
|
i = 0,
|
||||||
|
nodeType = elem.nodeType;
|
||||||
|
|
||||||
|
if ( !nodeType ) {
|
||||||
|
// If no nodeType, this is expected to be an array
|
||||||
|
while ( (node = elem[i++]) ) {
|
||||||
|
// Do not traverse comment nodes
|
||||||
|
ret += jQuery.text( node );
|
||||||
|
}
|
||||||
|
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||||||
|
// Use textContent for elements
|
||||||
|
return elem.textContent;
|
||||||
|
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||||||
|
return elem.nodeValue;
|
||||||
|
}
|
||||||
|
// Do not include comment or processing instruction nodes
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
contains: function( a, b ) {
|
||||||
|
var adown = a.nodeType === 9 ? a.documentElement : a,
|
||||||
|
bup = b && b.parentNode;
|
||||||
|
return a === bup || !!( bup && bup.nodeType === 1 && adown.contains(bup) );
|
||||||
|
},
|
||||||
|
isXMLDoc: function( elem ) {
|
||||||
|
return (elem.ownerDocument || elem).documentElement.nodeName !== "HTML";
|
||||||
|
},
|
||||||
|
expr: {
|
||||||
|
match: {
|
||||||
|
needsContext: /^[\x20\t\r\n\f]*[>+~]/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.extend( jQuery.find, {
|
||||||
|
matches: function( expr, elements ) {
|
||||||
|
return jQuery.find( expr, null, null, elements );
|
||||||
|
},
|
||||||
|
matchesSelector: function( elem, expr ) {
|
||||||
|
return matches.call( elem, expr );
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user