jquery / sizzle Goto Github PK
View Code? Open in Web Editor NEWA sizzlin' hot selector engine.
Home Page: https://sizzlejs.com
License: Other
A sizzlin' hot selector engine.
Home Page: https://sizzlejs.com
License: Other
Sizzle's proprietary selectors should use a vendor prefix to ensure that it won't find itself in a position where it interferes with evolution in the syntax or finds one of its extensions standardized in an incompatible way. http://www.w3.org/TR/CSS21/syndata.html#vendor-keywords
For compatibility, all current selector extensions should be supported in both prefixed and unprefixed variations, but authors should be advised to use the prefixed variation and the unprefixed variation marked deprecated.
I believe the move to CSS3 selectors has become huge and, so far, Sizzle lacks support to several of the new selectors. The table on http://selectivizr.com/ shows how far behind it is compared to other Javascript frameworks. It shouldn't be too much of a hassle, and it would fix some of the issues in the issue queue.
Edit:
:lang()
:link
:visited
:target
:hover // this requires adding a special event to the DOM in unsupported browsers, we're not going to do this
:nth-last-child
:nth-of-type
:nth-last-of-type
:first-of-type
:last-of-type
:only-of-type
:root
In the source I only found the original sizzle.js file (26 KB) not the minified one, any idea where to find the minified?
Some adjacent sibling selectors prefixed by :first do not seem to work since jQuery 1.4.3. This regession does not affect selectors prefixed by :first-child.
A test case is available at http://jsfiddle.net/mxcurioni/hryGh/
Somehow this doesn't work. I'd expect to see in the console 1
, true
, 1
, but instead it's 0
for the one using filter
.
<html>
<head>
<title>jQuery "filter" test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
console.log($("[data-test]").length);
console.log($(document).children().eq(0).is("[data-test]"));
console.log($(document).children().filter("[data-test]").length);
});
</script>
</head>
<body>
<div data-test>Hi, I'm a div.</div>
</body>
</html>
Great work! Small request: could you please create a tag for the 1.0 version?
Syntax error, unrecognized expression: ...
querySelectorAll fails as well: SYNTAX_ERR: DOM Exception 12
Reported from Chrome.
It seems to be failing on the : character.
Brief Description:
VML elements within jQuery break Sizzel.selectors.filters.* internally when elem.type is accessed.
Story Description:
I know VML is a topic that tends to get ignored, but it seems to be breaking Sizzle.selectors.filters.* (particularly where ever elem.type is called). I'll try and liven it up a bit. If a VML object happens to wander into a jQuery element and is asked to be filtered, IE will exclaim, "Um, What? You have a .type? Why didn't anyone tell me?!". What's worse is IE will wander off your jQuery chain gang and into exception land where no more work can be done. And even that is fine as long as it's 5 o'clock and it's time to head home. But it turns out this isn't such a good thing at any other time of the day. Can we find a way for VML not to wander into jQuery, and if it does, not ask it about it's .type? Maybe we can find something else to ask it first.
I wish Sizzle supported a ":heading" selector, as an alias of the ":header" selector, since (strictly speaking) I think that <h1>, <h2>, etc. are "headings" not "headers"? http://www.w3.org/TR/html401/struct/global.html#h-7.5.5
EDIT: apparently github can't handle inline HTML. The correct post is also placed here:
http://pastebin.com/sbJ5h9R5
======================old, broken message===================
Try the following code in Google Chrome:
Basically it's just a matter of getting rid of the (3) instances of "+)+" in the regex (which are all non-capturing, so it doesn't change the results of exec either):
chunker, currently
/((?:((?:([^()]+)|[^()]+)+)|[(?:[[^[]]]|['"][^'"]['"]|[^[]'"]+)+]|.|[^ >+,([]+)+|[>+])(\s_,\s_)?((?:.|\r|\n))/g
would become
/((?:((?:([^()]+)|[^()])+)|[(?:[[^[]]]|['"][^'"]['"]|[^[]'"])+]|.|[^ >+,([])+|[>+])(\s,\s_)?((?:.|\r|\n)_)/g
Error appears in FF 3.5
on query: "input:not(input[type=hidden]):not(input[type=image]):not(input[type=button]):not(input[type=reset]):not(input[type=submit]), textarea, select"
I can send document html on which I get that error (it's reproducible always on my side)
I've fixed it temporarily on my side by changing:
if (chunker.exec(match[3]).length > 1 || /^\w/.test(match[3]) ) {
into
var res = chunker.exec(match[3])
if ((res && res.length > 1) || /^\w/.test(match[3]) ) {
Currently new selectors cannot be added via the extension API documented in the wiki.
The issue is the leftMatch
object-literal, which is filled by the follow code at initialization time:
for ( var type in Expr.match ) {
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
}
We need this code to be publicly exposed so that we can run it after adding new selectors via the extension API.
I've hacked around this by creating a new method (using Sizzle via jQuery):
Expr = $.expr;
Expr.process = function(type) {
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^[]_])(?![^(]_))/.source );
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/(\d+)/g, function(all, num){
return "" + (num - 0 + 1);
}));
};
which I use like this:
$.expr.match['WIDGET'] = /@((?:[\w\u00c0-\uFFFF\-]|\\.)+)/;
$.expr.preFilter.WIDGET = function(match) {
return match[1].replace(/\\/g, "");
};
$.expr.filter.WIDGET = function(elem, match) {
return elem.getAttribute('data-widget') === match;
};
$.expr.process('WIDGET')
Sizzle needs to expose the code that fills the leftMatch
object via a function that works something like the one I've shown here.
Following the instructions (i.e. open test/index.html) results in an error: "module is not defined". I'm guessing this is because qunit isn't in the zip file.
If you use a document fragment as context, Sizzle fails because it tries to use context.getElementsByTagName().
Making it possible would mean using a getElementByTagName(context, tagName) function either using context.getElementsByTagName(tagName) or checking in context.childNodes which ones have the good tagName depneding on if there the method is available or not.
Or checking if element is fragment and if it is, adding the method working as described above.
The unit tests for broken selectors in sizzle test to see if the caught error message contains "Syntax error" but in IE (6 and 8, at least) the error message being thrown is "Object doesn't support this property or method."
This selector:
$(xml).find("routeStop:gt(0) load integer, routeStop:gt(0) unload integer").each(function(index){
});
Throws the following in IE7 (however it doesn't throw an error in IE8 running as IE7):
"Number expected"
...
if (sortOrder) {
hasDuplicate = false;
result.sort(sortOrder); <== error on this line
if (hasDuplicate){
....
If you need more detail I can try to scrounge it up.
It would be useful to support Namespaces for selectors, preferably the CSS Namespaces Module if possible, or some similar method.
Consider the following elements:
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" />
and
<entry xmlns:"http://www.w3.org/2005/Atom" />
The selector atom:entry
is required for the former, and entry
for the latter. Without knowing the exact prefixes used, it can be difficult to parse namespaced documents.
My suggestion, based on the CSS Namespace Module, would be something like this:
Sizzle.namespace("http://www.example.com/foo"); // Sets the default namespace
Sizzle.namespace("bar", "http://www.example.com/foo"); // Sets the namespace for the `bar` prefix
Sizzle("bar|foo") // Matches `foo` in the namespace denoted by `bar`
Sizzle("*|foo") // Matches `foo` in any namespace
Sizzle("|foo") // Matches `foo` with no namespace
Sizzle("foo"); // Matches `foo` in the default namespace
This selector input[id=01234567890123456789012345678901234567890123456789
(note that there is no closing ]
) causes IE 9 to hang.
I think this is because the regex used suffers from catastrophic backtracking when a match can't be found.
I tested the above using jQuery 1.7. I'm not sure what version of sizzle that applies to.
/via @dperini: http://twitter.com/diegoperini/status/158523985703870464
:root
should map to document.documentElement
.
Attribute selectors fail whenever the selector value contains a single quote. I've added a test case that shows this in markstory@854de47124424b531b3dc136a64a9a39eb2ee7d2
I'll try and make a patch for the solution as well.
When Sizzle is using the browser implementation with querySelectorAll
, this example:
<script src="https://raw.github.com/jquery/sizzle/master/sizzle.js"></script>
<a href="/foo" my-attr="">dead link</a>
<script type="text/javascript">
console.log( Sizzle('a[my-attr]') );
</script>
returns me [a /foo]
However, when using the internal implementation, the result is different (I used this trick to undefine the browsers querySelectorAll implementation):
<script type="text/javascript">
document.querySelectorAll = undefined;
</script>
<script src="https://raw.github.com/jquery/sizzle/master/sizzle.js"></script>
<a href="/foo" my-attr="">dead link</a>
<script type="text/javascript">
console.log( Sizzle('a[my-attr]') );
</script>
Returns me: [ ]
This becomes a cross browser issue when e.g. using IE in a HTML document without DOCTYPE; at least in the versions I tested (IE9, IE8) and document without (recognized?) doctype does not expose querySelectorAll
so Sizzle defaults to its internal implementation which doesn't match what browsers do.
Issue 24 [1] reads similar but I'm not sure if it's really related.
[1] #24
Given a document containing the following element:
The following lines returns:
var input = Sizzle('[required]')[0]; //input#field
Sizzle.matches('[required]', [input]); // [ ]
When there is an iframe with a cross domain source, the :text selector fails in IE7 with the error "Permission denied". The problem lies in line 625:
var attr = elem.getAttribute( "type" ), type = elem.type;
For some reason, getAttribute("type") is not allowed on cross domain iframes in IE7. A possible solution would be to only check the attribute when the element indeed is an input element:
text: function( elem ) {
var attr, type;
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && (type = elem.type, attr = elem.getAttribute("type"), "text" === type) && ( attr === type || attr === null );
},
See http://jsfiddle.net/VvnGm/ for an example
When an input element's name contains a dot and brackets, it fails to find this element with :input selector.
Tests for this bug:
t( "Attribute containing dot and []", 'input[name="foo.name[bar]"]', ["hiddenBar"] ); //it passes
t( "Attribute containing dot and []", ':input[name="foo.name[bar]"]', ["hiddenBar"] ); //it should pass
t( "Attribute containing dot and []", 'input[name="foo.name[0]"]', ["hidden0"] ); //it passes
t( "Attribute containing dot and []", ':input[name="foo.name[0]"]', ["hidden0"] ); //it should pass
The elements in index.html:
<input type="text" style="display:none;" name="foo.name[bar]" id="hiddenBar"/>
<input type="text" style="display:none;" name="foo.name[0]" id="hidden0"/>
I've noticed this bug when I wrote a testcase in AngularJS: wanted to enter some text into my input which name was "invoice.Customer.AddressLine[0]".
Attribute selectors fail in IE when attribute name looks like ns:attr
and attribute doesn't exist.
For example: Sizzle("[ui\\:custom]")
doesn't works when selector find some table
without attribute ui:custom
And elem.getAttribute( name )
fails too when name like ns:attr for any type of DOM elements, so it's better to use elem.attributes.getNamedItem
I made changes to my copy of https://github.com/jquery/sizzle/blob/1.5.1rc1/sizzle.js in lines 803 — 805
was
803: elem[ name ] != null ? 804: elem[ name ] : 805: elem.getAttribute( name ),
now
803: "TABLE" !== elem.nodeName && elem[ name ] != null ? 804: elem[ name ] : 805: elem.attributes ? 806: elem.attributes.getNamedItem(name) : 807: null,
Works fine
VML objects which make it into sizzle cause errors in IE7 and IE8. A test case can be found here: https://gist.github.com/2b7abeffc4573accc994 (Thank's to jfirebaugh for making the initial tests)
Also reported here: http://www.sitecrafting.com/blog/jquery-cufon-dont-mix/#update_2010-07-14
If I want to find all the paragraphs after a certain element, using that element as a context to search from, this is currently not possible, it seems to me.
Suppose you had this HTML:
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</div>
If I wanted to get the last two paragraphs and had paragraph no. 3 already referenced as a DOM element (let's call it "para"), I'd like to be able to do this:
$('~ p', para);
This might sound like a silly/niche requirement, but it's useful when using events that have been applied to lots of similar elements in a container, and you want to access all the siblings after the one that was clicked (or whatever the event was).
EDIT:
This also applies to the child selector, >. If I wanted to access all SPAN elements within a paragraph (that I had as a DOM element), but only direct children (not grandchildren, etc).
<p>
<span>A</span>
<span>B</span>
<a href="#"><span>C</span></a>
</p>
In the example above, only A and B would be selected, using a syntax like this:
$('> span', para);
Again, this is useful if the exact identity of the "para" element is not known.
Example can be found at http://jsfiddle.net/ZUs8f/3/ .
JQuery.fn.is
function uses Sizzle.matches
method when there are several elements and Sizzle.matchesSelector
when there is only one. Both Sizzle.matchesSelector
and Sizzle.matches
use Sizzle
function underneath except in one case - https://github.com/jquery/sizzle/blob/master/sizzle.js#L1241 if browser supports it or selector is appropriate then Sizzle uses native matches selector.
But results of Sizzle
function are different from mozMatchesSelector and webkitMatchesSelector if we use [value="something"]
selector. These native matchers use initial value of the attribute, not the one changed by user as Sizzle does.
Example provided at the beginning shows inconsistent results on chrome/safari/firefox. Simple solution would be to change:
!/!=/.test( expr )
to
!/!=|\[ *value[ =]/.test( expr )
The style attribute should be retrieved with getAttribute('style') I guess?
I understand that each browser render css text differently but it is still better than nothing.
See here:
http://bugs.jquery.com/ticket/8105
While attempting to fix the global variables with JSLint, I found this one:
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
where Range doesnt appear to have any reference. It's possibly a typo of aRange?
Sizzle supports data attribute selectors when they include dashes and underscores, but not when they include periods. This would be useful. Periods are valid in the naming rules.
data-example1.0="This is a valid in HTML5 "
data-example1-0="This is a valid in HTML5 "
$( '[data-example1-0]' ) // Targetable in jQuery.
$( '[data-example1.0]' ) // Throws "unrecognized expression" Sizzle error in jQuery.
Trying to run the unit tests for Sizzle CSS Selector Engine - v1.0 at sizzle/test/index.html results in this failing error stack:
too much recursion
test (line 53)
too much recursion
return (function (a, b) {
qunit.js (line 820)
too much recursion
})(args[0], args[1]) && argument...(this, args.splice(1, args.length -1));
qunit.js (line 830)
too much recursion
if ( ! innerEquiv(a[i], b[i])) {
qunit.js (line 797)
too much recursion
return callbacks[prop].apply(callbacks, args);
qunit.js (line 706)
too much recursion
return bindCallbacks(a, callbacks, [b, a]);
qunit.js (line 826)
This happens in Safari 4.0.3, Mac Opera 9.64 and Mac FireFox 3.0.10, at least.
Sizzle comes with a an :nth-child()
selector, but lacks an :nth-of-type()
selector.
This doesn't seem to be very easy to implement as a custom selector in jQuery either. To illustrate the difference between :nth-child()
and :nth-of-type()
, as well as some of the problems in trying to write a custom jQuery filter for this, I'd like to refer to this Stack Overflow topic: :nth-of-type()
in jQuery / Sizzle?
If an element has a classname such as "foo\nbar", it is not possible to query for it by the selectors ".foo" or ".bar".
The bug is rather obvious: the matching is done by checking " ", and not by other whitespace characters such as newline, tab etc.
Proposed fix: match by regexp instead, example: /\s<class_escaped>\s/.test(" " + element.className + " ")
Work-around: wrap every class in spaces in the class-attribute on the element.
Sizzle code contains memory leak patterns as documented in http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx - In particular the DOM insertion order pattern.
Eg. - Current IE leaky code:
// We're going to inject a fake input element with a specified name
var form = document.createElement("div"),
id = "script" + (new Date()).getTime();
form.innerHTML = "";
// Inject it into the root element, check its status, and remove it quickly
var root = document.documentElement;
root.insertBefore( form, root.firstChild );
Modified IE no-more-leaky code:
// We're going to inject a fake input element with a specified name
var form = document.createElement("div"),
id = "script" + (new Date()).getTime();
// Inject it into the root element, check its status, and remove it quickly
var root = document.documentElement;
root.insertBefore( form, root.firstChild );
// Add element to DOM before performing innerHTML to prevent memory leaks in IE
form.innerHTML = "<a name='" + id + "'/>";
http://github.com/jeresig/sizzle/blob/master/sizzle.js#L510
If called on a disconnected element it will try to access a property of the null parentNode.
line 1110
return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
needs to escape "." in nid
This is related to jQuery bug ticket 7205 ( http://bugs.jquery.com/ticket/7205 ).
In essence, there is a discrepancy between what is resultant from invalid selections ">child" and when passing a type selector to a filter's selection such as "type:has(>child)".
I have not yet researched broad enough into the issue to see if this exists outside of the :has() filter, or can be reproduced with other selectors.
Copied from http://bugs.jquery.com/ticket/11109
Test case: http://jsfiddle.net/JBBM8/
Because Sizzle.selectors.relative
functions "return" only a single match, Sizzle can be trapped into a false negative with respect to preceding parts of the full selector when the relative selector tests against multiple elements (e.g., "~"
and ""
).
I'm pretty sure that fixing this will require changing the Sizzle.selectors.relative
Extension API to allow "returning" arrays, so I will hold off working on this until the core team weighs in with their comments/approval.
Technical explanation: Given a query like "A + B ~ C"
, Sizzle:
C
, thenSizzle.selectors.relative["~"]
to replace each element with the first preceding sibling element matching B
(or false
if nonexistent), thenSizzle.selectors.relative["+"]
to replace each element with the preceding sibling element if it matches A
(or false
if it doesn't), thenfalse
through all subsequent stepsThe problem here is that step 2 fails to report back all preceding siblings matching B
, erroneously restricting the input set for subsequent step 3.
You should use the hasOwnProperty() method in your for(var attribute in object) loops.
Line 212:
for ( var type in Expr.filter ) {/* correction -> */ if (Expr.filter.hasOwnProperty(type)) {
Of course, you have to add a } on line 271 too.
If you don't think it's an issue, try using Sizzle with that code in the same HTML page :
Object.prototype.whatever = function(){};
In IE 6.0.2900 the code below will (wrongly?) alert "splat". Unfortunately the testing framework for Sizzle follows this exact same pattern by defining window.jQuery
in sizzle/test/jquery.js (line 5568) and then conditionally redefining jQuery using var
in /sizzle/test/data/testinit.js (line 1).
In the case of sizzle this makes it impossible to run any unit tests in IE 6. Removing the var
from /sizzle/test/data/testinit.js (line 1) will avoid the issue.
<script type="text/javascript">
window.jQuery = 'hello';
</script>
<script type="text/javascript">
var jQuery = window.jQuery || 'splat';
alert(jQuery);
</script>
'when will jQuery have standard CSS2.1 compliant regular expression matching "identifiers" ? Range \u00C0-\uFFFF is wrong !' - @diegoperini (https://twitter.com/#!/diegoperini/status/68236401879154688)
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B&W?" or "B\26 W\3F".
Note that Unicode is code-by-code equivalent to ISO 10646 (see [UNICODE] and [ISO10646]).
source: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
If a selector includes the backslash (''), it will always fails to find any elements. This is true for attribute, class, and id selector expressions:
Test HTML: the foo bar
Expression: Sizzle("#foo\bar") (or Sizzle(".foo\bar"), Sizzle("[id='foo\bar']") )
Expected Result: [...]
Actual Result: []
This is related to jQuery issue http://bugs.jquery.com/ticket/10270.
A couple times now I’ve committed patches that pass the Sizzle selector tests but bomb out with jslint when they get pulled into jQuery; mea culpa for not checking there too, but Sizzle should probably run its own jslint as part of the build.
Dear Sizzle Devs,
While working with Sizzle I found a minor but annoying issue.
I have a dom tree that looks like this:
<div id="foo">
<span data-foo></span>
</div>
Now when I execute this:
Sizzle("[data-foo]").length;
I get 1, which is obviously correct, but when I provide a context:
Sizzle("[data-foo]", document.getElementById("foo")).length;
It returns 0, which is wrong.
Some more information:
Here's a demo of the problem (including tests with native querySelectorAll):
http://tifftiff.de/sizzle_bug/
The problem exists in my Chrome 6, Safari 5, IE 8 and Firefox 3.6/4.0b.
In IE 6+7 both tests return 0 regardless of the given context.
Sorry for the long absence,
I think there's still an open bug in sibling selector, when the search match is in the checkSet (this means that "div ~ div" doesn't work).
This is fixed removing the following codes from dirNode and dirNodeCheck:
1: (it becames obsolete)
var sibDir = dir == "previousSibling" && !isXML;
2:
if ( sibDir && elem.nodeType === 1 ) {
elem.sizcache = doneName;
elem.sizset = i;
}
It was a speed optimization I made, but it fails under that particular condition.
My apologies,
--Fabio
In Chrome 12.0.742.30 dev-m the input:focus test fails when running tests in an unfocused tab.
To reproduce open the qunit test in a background tab and let it run.
1. selector: pseudo - misc (2, 17, 19)
Element focused (input:focus)
Expected:
[
<input id="focus-input"></input>
]
Result:
[]
Diff:
[
<input id="focus-input"></input>
] []
Source:
at t (http://cloud9ide.com/davidmurdoch/sizzle/workspace/test/data/testinit.js:33:2)
:focus Matches
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.