Skip to content
Permalink
Browse files

Added UTF8 Selector support (#1001) and fixed infinite selector loops (

…#1025). You can now select elements by UTF8-based IDs, classes, and attributes.
  • Loading branch information
jeresig committed Mar 25, 2007
1 parent ec2b688 commit af79bb1f255433d553d8d9dde0306cc340903c1a
Showing with 210 additions and 169 deletions.
  1. +6 −0 build/test/index.html
  2. +27 −15 src/selector/selector.js
  3. +177 −154 src/selector/selectorTest.js
@@ -1,5 +1,6 @@
<html id="html">
<head>
<meta http-equiv="Content-Type" content="text/css; charset=utf-8" />
<title>jQuery Test Suite</title>
<link rel="Stylesheet" media="screen" href="data/testsuite.css" />
<script type="text/javascript" src="../dist/jquery.js"></script>
@@ -77,6 +78,11 @@ <h2 id="userAgent"></h2>
<param name="p1" value="x1" />
<param name="p2" value="x2" />
</object>

<span id="台北Táiběi"></span>
<span id="台北" lang="中文"></span>
<span id="utf8class1" class="台北Táiběi 台北"></span>
<span id="utf8class2" class="台北"></span>
</form>
<b id="floatTest">Float test.</b>
<iframe id="iframe"></iframe>
@@ -67,16 +67,16 @@ jQuery.extend({
// The regular expressions that power the parsing engine
parse: [
// Match: [@value='test'], [@foo]
/^\[ *(@)([a-z0-9_-]*) *([!*$^=]*) *('?"?)(.*?)\4 *\]/i,
/^\[ *(@)([\w-]+) *([!*$^=]*) *('?"?)(.*?)\4 *\]/i,

// Match: [div], [div p]
/^(\[)\s*(.*?(\[.*?\])?[^[]*?)\s*\]/,

// Match: :contains('foo')
/^(:)([a-z0-9_-]*)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/i,
/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/i,

// Match: :even, :last-chlid
/^([:.#]*)([a-z0-9_*-]*)/i
// Match: :even, :last-chlid, #id, .class
/^([:.#]*)([\w\u0128-\uFFFF*-]+)/i
],

token: [
@@ -134,21 +134,21 @@ jQuery.extend({
}

// Initialize the search
var ret = [context], done = [], last = null;
var ret = [context], done = [], last;

// Continue while a selector expression exists, and while
// we're no longer looping upon ourselves
while ( t && last != t ) {
var r = [];
last = t;

t = jQuery.trim(t).replace( /^\/\//i, "" );
t = jQuery.trim(t).replace( /^\/\//, "" );

var foundToken = false;

// An attempt at speeding up child selectors that
// point to a specific element tag
var re = /^[\/>]\s*([a-z0-9*-]+)/i;
var re = /^[\/>]\s*([\w*-]+)/i;
var m = re.exec(t);

if ( m ) {
@@ -205,7 +205,7 @@ jQuery.extend({

} else {
// Optomize for the case nodeName#idName
var re2 = /^([a-z0-9_-]+)(#)([a-z0-9\\*_-]*)/i;
var re2 = /^(\w+)(#)([\w\u0128-\uFFFF*-]+)/i;
var m = re2.exec(t);

// Re-organize the results, so that they're consistent
@@ -215,21 +215,21 @@ jQuery.extend({
} else {
// Otherwise, do a traditional filter check for
// ID, class, and element selectors
re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
re2 = /^([#.]?)([\w\u0128-\uFFFF*-]*)/i;
m = re2.exec(t);
}

var last = ret[ret.length-1];
var elem = ret[ret.length-1];

// Try to do a global search by ID, where we can
if ( m[1] == "#" && last && last.getElementById ) {
if ( m[1] == "#" && elem && elem.getElementById ) {
// Optimization for HTML document case
var oid = last.getElementById(m[2]);
var oid = elem.getElementById(m[2]);

// Do a quick check for the existence of the actual ID attribute
// to avoid selecting by the name attribute in IE
if ( jQuery.browser.msie && oid && oid.id != m[2] )
oid = jQuery('[@id="'+m[2]+'"]', last)[0];
oid = jQuery('[@id="'+m[2]+'"]', elem)[0];

// Do a quick check for node name (where applicable) so
// that div#foo searches will be really fast
@@ -292,8 +292,14 @@ jQuery.extend({
}
}

// An error occurred with the selector;
// just return an empty set instead
if ( t )
ret = [];

// Remove the root context
if ( ret && ret[0] == context ) ret.shift();
if ( ret && ret[0] == context )
ret.shift();

// And combine the results
done = jQuery.merge( done, ret );
@@ -302,8 +308,11 @@ jQuery.extend({
},

filter: function(t,r,not) {
var last;

// Look for common filter expressions
while ( t && /^[a-z[({<*:.#]/i.test(t) ) {
while ( t && t != last ) {
last = t;

var p = jQuery.parse, m;

@@ -325,6 +334,9 @@ jQuery.extend({
}
});

if ( !m )
continue;

// :not() is a special case that can be optimized by
// keeping it out of the expression list
if ( m[1] == ":" && m[2] == "not" )

0 comments on commit af79bb1

Please sign in to comment.
You can’t perform that action at this time.