sizzle.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. /*!
  2. * Sizzle CSS Selector Engine - v1.0
  3. * Copyright 2009, The Dojo Foundation
  4. * Released under the MIT, BSD, and GPL Licenses.
  5. * More information: http://sizzlejs.com/
  6. */
  7. (function(){
  8. var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
  9. done = 0,
  10. toString = Object.prototype.toString,
  11. hasDuplicate = false,
  12. baseHasDuplicate = true;
  13. // Here we check if the JavaScript engine is using some sort of
  14. // optimization where it does not always call our comparision
  15. // function. If that is the case, discard the hasDuplicate value.
  16. // Thus far that includes Google Chrome.
  17. [0, 0].sort(function(){
  18. baseHasDuplicate = false;
  19. return 0;
  20. });
  21. var Sizzle = function(selector, context, results, seed) {
  22. results = results || [];
  23. context = context || document;
  24. var origContext = context;
  25. if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
  26. return [];
  27. }
  28. if ( !selector || typeof selector !== "string" ) {
  29. return results;
  30. }
  31. var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
  32. soFar = selector, ret, cur, pop, i;
  33. // Reset the position of the chunker regexp (start from head)
  34. do {
  35. chunker.exec("");
  36. m = chunker.exec(soFar);
  37. if ( m ) {
  38. soFar = m[3];
  39. parts.push( m[1] );
  40. if ( m[2] ) {
  41. extra = m[3];
  42. break;
  43. }
  44. }
  45. } while ( m );
  46. if ( parts.length > 1 && origPOS.exec( selector ) ) {
  47. if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
  48. set = posProcess( parts[0] + parts[1], context );
  49. } else {
  50. set = Expr.relative[ parts[0] ] ?
  51. [ context ] :
  52. Sizzle( parts.shift(), context );
  53. while ( parts.length ) {
  54. selector = parts.shift();
  55. if ( Expr.relative[ selector ] ) {
  56. selector += parts.shift();
  57. }
  58. set = posProcess( selector, set );
  59. }
  60. }
  61. } else {
  62. // Take a shortcut and set the context if the root selector is an ID
  63. // (but not if it'll be faster if the inner selector is an ID)
  64. if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
  65. Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
  66. ret = Sizzle.find( parts.shift(), context, contextXML );
  67. context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
  68. }
  69. if ( context ) {
  70. ret = seed ?
  71. { expr: parts.pop(), set: makeArray(seed) } :
  72. Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
  73. set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
  74. if ( parts.length > 0 ) {
  75. checkSet = makeArray(set);
  76. } else {
  77. prune = false;
  78. }
  79. while ( parts.length ) {
  80. cur = parts.pop();
  81. pop = cur;
  82. if ( !Expr.relative[ cur ] ) {
  83. cur = "";
  84. } else {
  85. pop = parts.pop();
  86. }
  87. if ( pop == null ) {
  88. pop = context;
  89. }
  90. Expr.relative[ cur ]( checkSet, pop, contextXML );
  91. }
  92. } else {
  93. checkSet = parts = [];
  94. }
  95. }
  96. if ( !checkSet ) {
  97. checkSet = set;
  98. }
  99. if ( !checkSet ) {
  100. Sizzle.error( cur || selector );
  101. }
  102. if ( toString.call(checkSet) === "[object Array]" ) {
  103. if ( !prune ) {
  104. results.push.apply( results, checkSet );
  105. } else if ( context && context.nodeType === 1 ) {
  106. for ( i = 0; checkSet[i] != null; i++ ) {
  107. if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
  108. results.push( set[i] );
  109. }
  110. }
  111. } else {
  112. for ( i = 0; checkSet[i] != null; i++ ) {
  113. if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
  114. results.push( set[i] );
  115. }
  116. }
  117. }
  118. } else {
  119. makeArray( checkSet, results );
  120. }
  121. if ( extra ) {
  122. Sizzle( extra, origContext, results, seed );
  123. Sizzle.uniqueSort( results );
  124. }
  125. return results;
  126. };
  127. Sizzle.uniqueSort = function(results){
  128. if ( sortOrder ) {
  129. hasDuplicate = baseHasDuplicate;
  130. results.sort(sortOrder);
  131. if ( hasDuplicate ) {
  132. for ( var i = 1; i < results.length; i++ ) {
  133. if ( results[i] === results[i-1] ) {
  134. results.splice(i--, 1);
  135. }
  136. }
  137. }
  138. }
  139. return results;
  140. };
  141. Sizzle.matches = function(expr, set){
  142. return Sizzle(expr, null, null, set);
  143. };
  144. Sizzle.find = function(expr, context, isXML){
  145. var set;
  146. if ( !expr ) {
  147. return [];
  148. }
  149. for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
  150. var type = Expr.order[i], match;
  151. if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
  152. var left = match[1];
  153. match.splice(1,1);
  154. if ( left.substr( left.length - 1 ) !== "\\" ) {
  155. match[1] = (match[1] || "").replace(/\\/g, "");
  156. set = Expr.find[ type ]( match, context, isXML );
  157. if ( set != null ) {
  158. expr = expr.replace( Expr.match[ type ], "" );
  159. break;
  160. }
  161. }
  162. }
  163. }
  164. if ( !set ) {
  165. set = context.getElementsByTagName("*");
  166. }
  167. return {set: set, expr: expr};
  168. };
  169. Sizzle.filter = function(expr, set, inplace, not){
  170. var old = expr, result = [], curLoop = set, match, anyFound,
  171. isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
  172. while ( expr && set.length ) {
  173. for ( var type in Expr.filter ) {
  174. if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
  175. var filter = Expr.filter[ type ], found, item, left = match[1];
  176. anyFound = false;
  177. match.splice(1,1);
  178. if ( left.substr( left.length - 1 ) === "\\" ) {
  179. continue;
  180. }
  181. if ( curLoop === result ) {
  182. result = [];
  183. }
  184. if ( Expr.preFilter[ type ] ) {
  185. match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
  186. if ( !match ) {
  187. anyFound = found = true;
  188. } else if ( match === true ) {
  189. continue;
  190. }
  191. }
  192. if ( match ) {
  193. for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
  194. if ( item ) {
  195. found = filter( item, match, i, curLoop );
  196. var pass = not ^ !!found;
  197. if ( inplace && found != null ) {
  198. if ( pass ) {
  199. anyFound = true;
  200. } else {
  201. curLoop[i] = false;
  202. }
  203. } else if ( pass ) {
  204. result.push( item );
  205. anyFound = true;
  206. }
  207. }
  208. }
  209. }
  210. if ( found !== undefined ) {
  211. if ( !inplace ) {
  212. curLoop = result;
  213. }
  214. expr = expr.replace( Expr.match[ type ], "" );
  215. if ( !anyFound ) {
  216. return [];
  217. }
  218. break;
  219. }
  220. }
  221. }
  222. // Improper expression
  223. if ( expr === old ) {
  224. if ( anyFound == null ) {
  225. Sizzle.error( expr );
  226. } else {
  227. break;
  228. }
  229. }
  230. old = expr;
  231. }
  232. return curLoop;
  233. };
  234. Sizzle.error = function( msg ) {
  235. throw "Syntax error, unrecognized expression: " + msg;
  236. };
  237. var Expr = Sizzle.selectors = {
  238. order: [ "ID", "NAME", "TAG" ],
  239. match: {
  240. ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
  241. CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
  242. NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
  243. ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
  244. TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
  245. CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
  246. POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
  247. PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
  248. },
  249. leftMatch: {},
  250. attrMap: {
  251. "class": "className",
  252. "for": "htmlFor"
  253. },
  254. attrHandle: {
  255. href: function(elem){
  256. return elem.getAttribute("href");
  257. }
  258. },
  259. relative: {
  260. "+": function(checkSet, part){
  261. var isPartStr = typeof part === "string",
  262. isTag = isPartStr && !/\W/.test(part),
  263. isPartStrNotTag = isPartStr && !isTag;
  264. if ( isTag ) {
  265. part = part.toLowerCase();
  266. }
  267. for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
  268. if ( (elem = checkSet[i]) ) {
  269. while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
  270. checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
  271. elem || false :
  272. elem === part;
  273. }
  274. }
  275. if ( isPartStrNotTag ) {
  276. Sizzle.filter( part, checkSet, true );
  277. }
  278. },
  279. ">": function(checkSet, part){
  280. var isPartStr = typeof part === "string",
  281. elem, i = 0, l = checkSet.length;
  282. if ( isPartStr && !/\W/.test(part) ) {
  283. part = part.toLowerCase();
  284. for ( ; i < l; i++ ) {
  285. elem = checkSet[i];
  286. if ( elem ) {
  287. var parent = elem.parentNode;
  288. checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
  289. }
  290. }
  291. } else {
  292. for ( ; i < l; i++ ) {
  293. elem = checkSet[i];
  294. if ( elem ) {
  295. checkSet[i] = isPartStr ?
  296. elem.parentNode :
  297. elem.parentNode === part;
  298. }
  299. }
  300. if ( isPartStr ) {
  301. Sizzle.filter( part, checkSet, true );
  302. }
  303. }
  304. },
  305. "": function(checkSet, part, isXML){
  306. var doneName = done++, checkFn = dirCheck, nodeCheck;
  307. if ( typeof part === "string" && !/\W/.test(part) ) {
  308. part = part.toLowerCase();
  309. nodeCheck = part;
  310. checkFn = dirNodeCheck;
  311. }
  312. checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
  313. },
  314. "~": function(checkSet, part, isXML){
  315. var doneName = done++, checkFn = dirCheck, nodeCheck;
  316. if ( typeof part === "string" && !/\W/.test(part) ) {
  317. part = part.toLowerCase();
  318. nodeCheck = part;
  319. checkFn = dirNodeCheck;
  320. }
  321. checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
  322. }
  323. },
  324. find: {
  325. ID: function(match, context, isXML){
  326. if ( typeof context.getElementById !== "undefined" && !isXML ) {
  327. var m = context.getElementById(match[1]);
  328. return m ? [m] : [];
  329. }
  330. },
  331. NAME: function(match, context){
  332. if ( typeof context.getElementsByName !== "undefined" ) {
  333. var ret = [], results = context.getElementsByName(match[1]);
  334. for ( var i = 0, l = results.length; i < l; i++ ) {
  335. if ( results[i].getAttribute("name") === match[1] ) {
  336. ret.push( results[i] );
  337. }
  338. }
  339. return ret.length === 0 ? null : ret;
  340. }
  341. },
  342. TAG: function(match, context){
  343. return context.getElementsByTagName(match[1]);
  344. }
  345. },
  346. preFilter: {
  347. CLASS: function(match, curLoop, inplace, result, not, isXML){
  348. match = " " + match[1].replace(/\\/g, "") + " ";
  349. if ( isXML ) {
  350. return match;
  351. }
  352. for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
  353. if ( elem ) {
  354. if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
  355. if ( !inplace ) {
  356. result.push( elem );
  357. }
  358. } else if ( inplace ) {
  359. curLoop[i] = false;
  360. }
  361. }
  362. }
  363. return false;
  364. },
  365. ID: function(match){
  366. return match[1].replace(/\\/g, "");
  367. },
  368. TAG: function(match, curLoop){
  369. return match[1].toLowerCase();
  370. },
  371. CHILD: function(match){
  372. if ( match[1] === "nth" ) {
  373. // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
  374. var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
  375. match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
  376. !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
  377. // calculate the numbers (first)n+(last) including if they are negative
  378. match[2] = (test[1] + (test[2] || 1)) - 0;
  379. match[3] = test[3] - 0;
  380. }
  381. // TODO: Move to normal caching system
  382. match[0] = done++;
  383. return match;
  384. },
  385. ATTR: function(match, curLoop, inplace, result, not, isXML){
  386. var name = match[1].replace(/\\/g, "");
  387. if ( !isXML && Expr.attrMap[name] ) {
  388. match[1] = Expr.attrMap[name];
  389. }
  390. if ( match[2] === "~=" ) {
  391. match[4] = " " + match[4] + " ";
  392. }
  393. return match;
  394. },
  395. PSEUDO: function(match, curLoop, inplace, result, not){
  396. if ( match[1] === "not" ) {
  397. // If we're dealing with a complex expression, or a simple one
  398. if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
  399. match[3] = Sizzle(match[3], null, null, curLoop);
  400. } else {
  401. var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
  402. if ( !inplace ) {
  403. result.push.apply( result, ret );
  404. }
  405. return false;
  406. }
  407. } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
  408. return true;
  409. }
  410. return match;
  411. },
  412. POS: function(match){
  413. match.unshift( true );
  414. return match;
  415. }
  416. },
  417. filters: {
  418. enabled: function(elem){
  419. return elem.disabled === false && elem.type !== "hidden";
  420. },
  421. disabled: function(elem){
  422. return elem.disabled === true;
  423. },
  424. checked: function(elem){
  425. return elem.checked === true;
  426. },
  427. selected: function(elem){
  428. // Accessing this property makes selected-by-default
  429. // options in Safari work properly
  430. elem.parentNode.selectedIndex;
  431. return elem.selected === true;
  432. },
  433. parent: function(elem){
  434. return !!elem.firstChild;
  435. },
  436. empty: function(elem){
  437. return !elem.firstChild;
  438. },
  439. has: function(elem, i, match){
  440. return !!Sizzle( match[3], elem ).length;
  441. },
  442. header: function(elem){
  443. return (/h\d/i).test( elem.nodeName );
  444. },
  445. text: function(elem){
  446. return "text" === elem.type;
  447. },
  448. radio: function(elem){
  449. return "radio" === elem.type;
  450. },
  451. checkbox: function(elem){
  452. return "checkbox" === elem.type;
  453. },
  454. file: function(elem){
  455. return "file" === elem.type;
  456. },
  457. password: function(elem){
  458. return "password" === elem.type;
  459. },
  460. submit: function(elem){
  461. return "submit" === elem.type;
  462. },
  463. image: function(elem){
  464. return "image" === elem.type;
  465. },
  466. reset: function(elem){
  467. return "reset" === elem.type;
  468. },
  469. button: function(elem){
  470. return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
  471. },
  472. input: function(elem){
  473. return (/input|select|textarea|button/i).test(elem.nodeName);
  474. }
  475. },
  476. setFilters: {
  477. first: function(elem, i){
  478. return i === 0;
  479. },
  480. last: function(elem, i, match, array){
  481. return i === array.length - 1;
  482. },
  483. even: function(elem, i){
  484. return i % 2 === 0;
  485. },
  486. odd: function(elem, i){
  487. return i % 2 === 1;
  488. },
  489. lt: function(elem, i, match){
  490. return i < match[3] - 0;
  491. },
  492. gt: function(elem, i, match){
  493. return i > match[3] - 0;
  494. },
  495. nth: function(elem, i, match){
  496. return match[3] - 0 === i;
  497. },
  498. eq: function(elem, i, match){
  499. return match[3] - 0 === i;
  500. }
  501. },
  502. filter: {
  503. PSEUDO: function(elem, match, i, array){
  504. var name = match[1], filter = Expr.filters[ name ];
  505. if ( filter ) {
  506. return filter( elem, i, match, array );
  507. } else if ( name === "contains" ) {
  508. return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
  509. } else if ( name === "not" ) {
  510. var not = match[3];
  511. for ( var j = 0, l = not.length; j < l; j++ ) {
  512. if ( not[j] === elem ) {
  513. return false;
  514. }
  515. }
  516. return true;
  517. } else {
  518. Sizzle.error( "Syntax error, unrecognized expression: " + name );
  519. }
  520. },
  521. CHILD: function(elem, match){
  522. var type = match[1], node = elem;
  523. switch (type) {
  524. case 'only':
  525. case 'first':
  526. while ( (node = node.previousSibling) ) {
  527. if ( node.nodeType === 1 ) {
  528. return false;
  529. }
  530. }
  531. if ( type === "first" ) {
  532. return true;
  533. }
  534. node = elem;
  535. case 'last':
  536. while ( (node = node.nextSibling) ) {
  537. if ( node.nodeType === 1 ) {
  538. return false;
  539. }
  540. }
  541. return true;
  542. case 'nth':
  543. var first = match[2], last = match[3];
  544. if ( first === 1 && last === 0 ) {
  545. return true;
  546. }
  547. var doneName = match[0],
  548. parent = elem.parentNode;
  549. if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
  550. var count = 0;
  551. for ( node = parent.firstChild; node; node = node.nextSibling ) {
  552. if ( node.nodeType === 1 ) {
  553. node.nodeIndex = ++count;
  554. }
  555. }
  556. parent.sizcache = doneName;
  557. }
  558. var diff = elem.nodeIndex - last;
  559. if ( first === 0 ) {
  560. return diff === 0;
  561. } else {
  562. return ( diff % first === 0 && diff / first >= 0 );
  563. }
  564. }
  565. },
  566. ID: function(elem, match){
  567. return elem.nodeType === 1 && elem.getAttribute("id") === match;
  568. },
  569. TAG: function(elem, match){
  570. return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
  571. },
  572. CLASS: function(elem, match){
  573. return (" " + (elem.className || elem.getAttribute("class")) + " ")
  574. .indexOf( match ) > -1;
  575. },
  576. ATTR: function(elem, match){
  577. var name = match[1],
  578. result = Expr.attrHandle[ name ] ?
  579. Expr.attrHandle[ name ]( elem ) :
  580. elem[ name ] != null ?
  581. elem[ name ] :
  582. elem.getAttribute( name ),
  583. value = result + "",
  584. type = match[2],
  585. check = match[4];
  586. return result == null ?
  587. type === "!=" :
  588. type === "=" ?
  589. value === check :
  590. type === "*=" ?
  591. value.indexOf(check) >= 0 :
  592. type === "~=" ?
  593. (" " + value + " ").indexOf(check) >= 0 :
  594. !check ?
  595. value && result !== false :
  596. type === "!=" ?
  597. value !== check :
  598. type === "^=" ?
  599. value.indexOf(check) === 0 :
  600. type === "$=" ?
  601. value.substr(value.length - check.length) === check :
  602. type === "|=" ?
  603. value === check || value.substr(0, check.length + 1) === check + "-" :
  604. false;
  605. },
  606. POS: function(elem, match, i, array){
  607. var name = match[2], filter = Expr.setFilters[ name ];
  608. if ( filter ) {
  609. return filter( elem, i, match, array );
  610. }
  611. }
  612. }
  613. };
  614. var origPOS = Expr.match.POS,
  615. fescape = function(all, num){
  616. return "\\" + (num - 0 + 1);
  617. };
  618. for ( var type in Expr.match ) {
  619. Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
  620. Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
  621. }
  622. var makeArray = function(array, results) {
  623. array = Array.prototype.slice.call( array, 0 );
  624. if ( results ) {
  625. results.push.apply( results, array );
  626. return results;
  627. }
  628. return array;
  629. };
  630. // Perform a simple check to determine if the browser is capable of
  631. // converting a NodeList to an array using builtin methods.
  632. // Also verifies that the returned array holds DOM nodes
  633. // (which is not the case in the Blackberry browser)
  634. try {
  635. Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
  636. // Provide a fallback method if it does not work
  637. } catch(e){
  638. makeArray = function(array, results) {
  639. var ret = results || [], i = 0;
  640. if ( toString.call(array) === "[object Array]" ) {
  641. Array.prototype.push.apply( ret, array );
  642. } else {
  643. if ( typeof array.length === "number" ) {
  644. for ( var l = array.length; i < l; i++ ) {
  645. ret.push( array[i] );
  646. }
  647. } else {
  648. for ( ; array[i]; i++ ) {
  649. ret.push( array[i] );
  650. }
  651. }
  652. }
  653. return ret;
  654. };
  655. }
  656. var sortOrder;
  657. if ( document.documentElement.compareDocumentPosition ) {
  658. sortOrder = function( a, b ) {
  659. if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
  660. if ( a == b ) {
  661. hasDuplicate = true;
  662. }
  663. return a.compareDocumentPosition ? -1 : 1;
  664. }
  665. var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
  666. if ( ret === 0 ) {
  667. hasDuplicate = true;
  668. }
  669. return ret;
  670. };
  671. } else if ( "sourceIndex" in document.documentElement ) {
  672. sortOrder = function( a, b ) {
  673. if ( !a.sourceIndex || !b.sourceIndex ) {
  674. if ( a == b ) {
  675. hasDuplicate = true;
  676. }
  677. return a.sourceIndex ? -1 : 1;
  678. }
  679. var ret = a.sourceIndex - b.sourceIndex;
  680. if ( ret === 0 ) {
  681. hasDuplicate = true;
  682. }
  683. return ret;
  684. };
  685. } else if ( document.createRange ) {
  686. sortOrder = function( a, b ) {
  687. if ( !a.ownerDocument || !b.ownerDocument ) {
  688. if ( a == b ) {
  689. hasDuplicate = true;
  690. }
  691. return a.ownerDocument ? -1 : 1;
  692. }
  693. var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
  694. aRange.setStart(a, 0);
  695. aRange.setEnd(a, 0);
  696. bRange.setStart(b, 0);
  697. bRange.setEnd(b, 0);
  698. var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
  699. if ( ret === 0 ) {
  700. hasDuplicate = true;
  701. }
  702. return ret;
  703. };
  704. }
  705. // Utility function for retreiving the text value of an array of DOM nodes
  706. Sizzle.getText = function( elems ) {
  707. var ret = "", elem;
  708. for ( var i = 0; elems[i]; i++ ) {
  709. elem = elems[i];
  710. // Get the text from text nodes and CDATA nodes
  711. if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
  712. ret += elem.nodeValue;
  713. // Traverse everything else, except comment nodes
  714. } else if ( elem.nodeType !== 8 ) {
  715. ret += Sizzle.getText( elem.childNodes );
  716. }
  717. }
  718. return ret;
  719. };
  720. // Check to see if the browser returns elements by name when
  721. // querying by getElementById (and provide a workaround)
  722. (function(){
  723. // We're going to inject a fake input element with a specified name
  724. var form = document.createElement("div"),
  725. id = "script" + (new Date()).getTime();
  726. form.innerHTML = "<a name='" + id + "'/>";
  727. // Inject it into the root element, check its status, and remove it quickly
  728. var root = document.documentElement;
  729. root.insertBefore( form, root.firstChild );
  730. // The workaround has to do additional checks after a getElementById
  731. // Which slows things down for other browsers (hence the branching)
  732. if ( document.getElementById( id ) ) {
  733. Expr.find.ID = function(match, context, isXML){
  734. if ( typeof context.getElementById !== "undefined" && !isXML ) {
  735. var m = context.getElementById(match[1]);
  736. return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
  737. }
  738. };
  739. Expr.filter.ID = function(elem, match){
  740. var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
  741. return elem.nodeType === 1 && node && node.nodeValue === match;
  742. };
  743. }
  744. root.removeChild( form );
  745. root = form = null; // release memory in IE
  746. })();
  747. (function(){
  748. // Check to see if the browser returns only elements
  749. // when doing getElementsByTagName("*")
  750. // Create a fake element
  751. var div = document.createElement("div");
  752. div.appendChild( document.createComment("") );
  753. // Make sure no comments are found
  754. if ( div.getElementsByTagName("*").length > 0 ) {
  755. Expr.find.TAG = function(match, context){
  756. var results = context.getElementsByTagName(match[1]);
  757. // Filter out possible comments
  758. if ( match[1] === "*" ) {
  759. var tmp = [];
  760. for ( var i = 0; results[i]; i++ ) {
  761. if ( results[i].nodeType === 1 ) {
  762. tmp.push( results[i] );
  763. }
  764. }
  765. results = tmp;
  766. }
  767. return results;
  768. };
  769. }
  770. // Check to see if an attribute returns normalized href attributes
  771. div.innerHTML = "<a href='#'></a>";
  772. if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
  773. div.firstChild.getAttribute("href") !== "#" ) {
  774. Expr.attrHandle.href = function(elem){
  775. return elem.getAttribute("href", 2);
  776. };
  777. }
  778. div = null; // release memory in IE
  779. })();
  780. if ( document.querySelectorAll ) {
  781. (function(){
  782. var oldSizzle = Sizzle, div = document.createElement("div");
  783. div.innerHTML = "<p class='TEST'></p>";
  784. // Safari can't handle uppercase or unicode characters when
  785. // in quirks mode.
  786. if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
  787. return;
  788. }
  789. Sizzle = function(query, context, extra, seed){
  790. context = context || document;
  791. // Only use querySelectorAll on non-XML documents
  792. // (ID selectors don't work in non-HTML documents)
  793. if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) {
  794. try {
  795. return makeArray( context.querySelectorAll(query), extra );
  796. } catch(e){}
  797. }
  798. return oldSizzle(query, context, extra, seed);
  799. };
  800. for ( var prop in oldSizzle ) {
  801. Sizzle[ prop ] = oldSizzle[ prop ];
  802. }
  803. div = null; // release memory in IE
  804. })();
  805. }
  806. (function(){
  807. var div = document.createElement("div");
  808. div.innerHTML = "<div class='test e'></div><div class='test'></div>";
  809. // Opera can't find a second classname (in 9.6)
  810. // Also, make sure that getElementsByClassName actually exists
  811. if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
  812. return;
  813. }
  814. // Safari caches class attributes, doesn't catch changes (in 3.2)
  815. div.lastChild.className = "e";
  816. if ( div.getElementsByClassName("e").length === 1 ) {
  817. return;
  818. }
  819. Expr.order.splice(1, 0, "CLASS");
  820. Expr.find.CLASS = function(match, context, isXML) {
  821. if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
  822. return context.getElementsByClassName(match[1]);
  823. }
  824. };
  825. div = null; // release memory in IE
  826. })();
  827. function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
  828. for ( var i = 0, l = checkSet.length; i < l; i++ ) {
  829. var elem = checkSet[i];
  830. if ( elem ) {
  831. elem = elem[dir];
  832. var match = false;
  833. while ( elem ) {
  834. if ( elem.sizcache === doneName ) {
  835. match = checkSet[elem.sizset];
  836. break;
  837. }
  838. if ( elem.nodeType === 1 && !isXML ){
  839. elem.sizcache = doneName;
  840. elem.sizset = i;
  841. }
  842. if ( elem.nodeName.toLowerCase() === cur ) {
  843. match = elem;
  844. break;
  845. }
  846. elem = elem[dir];
  847. }
  848. checkSet[i] = match;
  849. }
  850. }
  851. }
  852. function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
  853. for ( var i = 0, l = checkSet.length; i < l; i++ ) {
  854. var elem = checkSet[i];
  855. if ( elem ) {
  856. elem = elem[dir];
  857. var match = false;
  858. while ( elem ) {
  859. if ( elem.sizcache === doneName ) {
  860. match = checkSet[elem.sizset];
  861. break;
  862. }
  863. if ( elem.nodeType === 1 ) {
  864. if ( !isXML ) {
  865. elem.sizcache = doneName;
  866. elem.sizset = i;
  867. }
  868. if ( typeof cur !== "string" ) {
  869. if ( elem === cur ) {
  870. match = true;
  871. break;
  872. }
  873. } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
  874. match = elem;
  875. break;
  876. }
  877. }
  878. elem = elem[dir];
  879. }
  880. checkSet[i] = match;
  881. }
  882. }
  883. }
  884. Sizzle.contains = document.compareDocumentPosition ? function(a, b){
  885. return !!(a.compareDocumentPosition(b) & 16);
  886. } : function(a, b){
  887. return a !== b && (a.contains ? a.contains(b) : true);
  888. };
  889. Sizzle.isXML = function(elem){
  890. // documentElement is verified for cases where it doesn't yet exist
  891. // (such as loading iframes in IE - #4833)
  892. var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
  893. return documentElement ? documentElement.nodeName !== "HTML" : false;
  894. };
  895. var posProcess = function(selector, context){
  896. var tmpSet = [], later = "", match,
  897. root = context.nodeType ? [context] : context;
  898. // Position selectors must be done after the filter
  899. // And so must :not(positional) so we move all PSEUDOs to the end
  900. while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
  901. later += match[0];
  902. selector = selector.replace( Expr.match.PSEUDO, "" );
  903. }
  904. selector = Expr.relative[selector] ? selector + "*" : selector;
  905. for ( var i = 0, l = root.length; i < l; i++ ) {
  906. Sizzle( selector, root[i], tmpSet );
  907. }
  908. return Sizzle.filter( later, tmpSet );
  909. };
  910. // EXPOSE
  911. window.Sizzle = Sizzle;
  912. })();