Nessuna descrizione

selector.js 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. QUnit.module( "selector", { afterEach: moduleTeardown } );
  2. /**
  3. * This test page is for selector tests that require jQuery in order to do the selection
  4. */
  5. QUnit.test( "element", function( assert ) {
  6. assert.expect( 7 );
  7. var fixture = document.getElementById( "qunit-fixture" );
  8. assert.deepEqual( jQuery( "p", fixture ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a Node context." );
  9. assert.deepEqual( jQuery( "p", "#qunit-fixture" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a selector context." );
  10. assert.deepEqual( jQuery( "p", jQuery( "#qunit-fixture" ) ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a jQuery object context." );
  11. assert.deepEqual( jQuery( "#qunit-fixture" ).find( "p" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a context via .find()." );
  12. assert.ok( jQuery( "#length" ).length, "<input name=\"length\"> cannot be found under IE, see #945" );
  13. assert.ok( jQuery( "#lengthtest input" ).length, "<input name=\"length\"> cannot be found under IE, see #945" );
  14. // #7533
  15. assert.equal( jQuery( "<div id=\"A'B~C.D[E]\"><p>foo</p></div>" ).find( "p" ).length, 1, "Find where context root is a node and has an ID with CSS3 meta characters" );
  16. } );
  17. QUnit.test( "id", function( assert ) {
  18. assert.expect( 26 );
  19. var a;
  20. assert.t( "ID Selector", "#body", [ "body" ] );
  21. assert.t( "ID Selector w/ Element", "body#body", [ "body" ] );
  22. assert.t( "ID Selector w/ Element", "ul#first", [] );
  23. assert.t( "ID selector with existing ID descendant", "#firstp #simon1", [ "simon1" ] );
  24. assert.t( "ID selector with non-existent descendant", "#firstp #foobar", [] );
  25. assert.t( "ID selector using UTF8", "#台北Táiběi", [ "台北Táiběi" ] );
  26. assert.t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", [ "台北Táiběi", "台北" ] );
  27. assert.t( "Descendant ID selector using UTF8", "div #台北", [ "台北" ] );
  28. assert.t( "Child ID selector using UTF8", "form > #台北", [ "台北" ] );
  29. assert.t( "Escaped ID", "#foo\\:bar", [ "foo:bar" ] );
  30. assert.t( "Escaped ID", "#test\\.foo\\[5\\]bar", [ "test.foo[5]bar" ] );
  31. assert.t( "Descendant escaped ID", "div #foo\\:bar", [ "foo:bar" ] );
  32. assert.t( "Descendant escaped ID", "div #test\\.foo\\[5\\]bar", [ "test.foo[5]bar" ] );
  33. assert.t( "Child escaped ID", "form > #foo\\:bar", [ "foo:bar" ] );
  34. assert.t( "Child escaped ID", "form > #test\\.foo\\[5\\]bar", [ "test.foo[5]bar" ] );
  35. assert.t( "ID Selector, child ID present", "#form > #radio1", [ "radio1" ] ); // bug #267
  36. assert.t( "ID Selector, not an ancestor ID", "#form #first", [] );
  37. assert.t( "ID Selector, not a child ID", "#form > #option1a", [] );
  38. assert.t( "All Children of ID", "#foo > *", [ "sndp", "en", "sap" ] );
  39. assert.t( "All Children of ID with no children", "#firstUL > *", [] );
  40. a = jQuery( "<a id='backslash\\foo'></a>" ).appendTo( "#qunit-fixture" );
  41. assert.t( "ID Selector contains backslash", "#backslash\\\\foo", [ "backslash\\foo" ] );
  42. assert.t( "ID Selector on Form with an input that has a name of 'id'", "#lengthtest", [ "lengthtest" ] );
  43. assert.t( "ID selector with non-existent ancestor", "#asdfasdf #foobar", [] ); // bug #986
  44. assert.t( "Underscore ID", "#types_all", [ "types_all" ] );
  45. assert.t( "Dash ID", "#qunit-fixture", [ "qunit-fixture" ] );
  46. assert.t( "ID with weird characters in it", "#name\\+value", [ "name+value" ] );
  47. } );
  48. QUnit.test( "class", function( assert ) {
  49. assert.expect( 4 );
  50. assert.deepEqual( jQuery( ".blog", document.getElementsByTagName( "p" ) ).get(), q( "mark", "simon" ), "Finding elements with a context." );
  51. assert.deepEqual( jQuery( ".blog", "p" ).get(), q( "mark", "simon" ), "Finding elements with a context." );
  52. assert.deepEqual( jQuery( ".blog", jQuery( "p" ) ).get(), q( "mark", "simon" ), "Finding elements with a context." );
  53. assert.deepEqual( jQuery( "p" ).find( ".blog" ).get(), q( "mark", "simon" ), "Finding elements with a context." );
  54. } );
  55. QUnit.test( "name", function( assert ) {
  56. assert.expect( 5 );
  57. var form;
  58. assert.t( "Name selector", "input[name=action]", [ "text1" ] );
  59. assert.t( "Name selector with single quotes", "input[name='action']", [ "text1" ] );
  60. assert.t( "Name selector with double quotes", "input[name=\"action\"]", [ "text1" ] );
  61. assert.t( "Name selector for grouped input", "input[name='types[]']", [ "types_all", "types_anime", "types_movie" ] );
  62. form = jQuery( "<form><input name='id'/></form>" ).appendTo( "body" );
  63. assert.equal( jQuery( "input", form[ 0 ] ).length, 1, "Make sure that rooted queries on forms (with possible expandos) work." );
  64. form.remove();
  65. } );
  66. QUnit.test( "selectors with comma", function( assert ) {
  67. assert.expect( 4 );
  68. var fixture = jQuery( "<div><h2><span></span></h2><div><p><span></span></p><p></p></div></div>" );
  69. assert.equal( fixture.find( "h2, div p" ).filter( "p" ).length, 2, "has to find two <p>" );
  70. assert.equal( fixture.find( "h2, div p" ).filter( "h2" ).length, 1, "has to find one <h2>" );
  71. assert.equal( fixture.find( "h2 , div p" ).filter( "p" ).length, 2, "has to find two <p>" );
  72. assert.equal( fixture.find( "h2 , div p" ).filter( "h2" ).length, 1, "has to find one <h2>" );
  73. } );
  74. QUnit.test( "child and adjacent", function( assert ) {
  75. assert.expect( 27 );
  76. assert.t( "Child", "p > a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
  77. assert.t( "Child", "p> a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
  78. assert.t( "Child", "p >a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
  79. assert.t( "Child", "p>a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
  80. assert.t( "Child w/ Class", "p > a.blog", [ "mark", "simon" ] );
  81. assert.t( "All Children", "code > *", [ "anchor1", "anchor2" ] );
  82. assert.selectInFixture( "All Grandchildren", "p > * > *", [ "anchor1", "anchor2" ] );
  83. assert.t( "Adjacent", "p + p", [ "ap", "en", "sap" ] );
  84. assert.t( "Adjacent", "p#firstp + p", [ "ap" ] );
  85. assert.t( "Adjacent", "p[lang=en] + p", [ "sap" ] );
  86. assert.t( "Adjacent", "a.GROUPS + code + a", [ "mark" ] );
  87. assert.t( "Element Preceded By", "#groups ~ a", [ "mark" ] );
  88. assert.t( "Element Preceded By", "#length ~ input", [ "idTest" ] );
  89. assert.t( "Element Preceded By", "#siblingfirst ~ em", [ "siblingnext", "siblingthird" ] );
  90. assert.t( "Element Preceded By (multiple)", "#siblingTest em ~ em ~ em ~ span", [ "siblingspan" ] );
  91. if ( jQuery.find.compile ) {
  92. assert.t( "Element Preceded By, Containing", "#liveHandlerOrder ~ div em:contains('1')", [ "siblingfirst" ] );
  93. assert.t( "Combinators are not skipped when mixing general and specific", "#siblingTest > em:contains('x') + em ~ span", [] );
  94. assert.equal( jQuery( "#listWithTabIndex li:eq(2) ~ li" ).length, 1, "Find by general sibling combinator (#8310)" );
  95. } else {
  96. assert.ok( "skip", ":contains not supported in selector-native" );
  97. assert.ok( "skip", ":contains not supported in selector-native" );
  98. assert.ok( "skip", ":eq not supported in selector-native" );
  99. }
  100. assert.t( "Multiple combinators selects all levels", "#siblingTest em *", [ "siblingchild", "siblinggrandchild", "siblinggreatgrandchild" ] );
  101. assert.t( "Multiple combinators selects all levels", "#siblingTest > em *", [ "siblingchild", "siblinggrandchild", "siblinggreatgrandchild" ] );
  102. assert.t( "Multiple sibling combinators doesn't miss general siblings", "#siblingTest > em:first-child + em ~ span", [ "siblingspan" ] );
  103. assert.equal( jQuery( "#listWithTabIndex" ).length, 1, "Parent div for next test is found via ID (#8310)" );
  104. assert.equal( jQuery( "#__sizzle__" ).length, 0, "Make sure the temporary id assigned by sizzle is cleared out (#8310)" );
  105. assert.equal( jQuery( "#listWithTabIndex" ).length, 1, "Parent div for previous test is still found via ID (#8310)" );
  106. assert.t( "Verify deep class selector", "div.blah > p > a", [] );
  107. assert.t( "No element deep selector", "div.foo > span > a", [] );
  108. assert.t( "Non-existent ancestors", ".fototab > .thumbnails > a", [] );
  109. } );
  110. QUnit.test( "attributes", function( assert ) {
  111. assert.expect( 54 );
  112. var attrbad, div, withScript;
  113. assert.t( "Find elements with a tabindex attribute", "[tabindex]", [ "listWithTabIndex", "foodWithNegativeTabIndex", "linkWithTabIndex", "linkWithNegativeTabIndex", "linkWithNoHrefWithTabIndex", "linkWithNoHrefWithNegativeTabIndex" ] );
  114. assert.t( "Attribute Exists", "#qunit-fixture a[title]", [ "google" ] );
  115. assert.t( "Attribute Exists (case-insensitive)", "#qunit-fixture a[TITLE]", [ "google" ] );
  116. assert.t( "Attribute Exists", "#qunit-fixture *[title]", [ "google" ] );
  117. assert.t( "Attribute Exists", "#qunit-fixture [title]", [ "google" ] );
  118. assert.t( "Attribute Exists", "#qunit-fixture a[ title ]", [ "google" ] );
  119. assert.t( "Boolean attribute exists", "#select2 option[selected]", [ "option2d" ] );
  120. assert.t( "Boolean attribute equals", "#select2 option[selected='selected']", [ "option2d" ] );
  121. assert.t( "Attribute Equals", "#qunit-fixture a[rel='bookmark']", [ "simon1" ] );
  122. assert.t( "Attribute Equals", "#qunit-fixture a[rel='bookmark']", [ "simon1" ] );
  123. assert.t( "Attribute Equals", "#qunit-fixture a[rel=bookmark]", [ "simon1" ] );
  124. assert.t( "Attribute Equals", "#qunit-fixture a[href='http://www.google.com/']", [ "google" ] );
  125. assert.t( "Attribute Equals", "#qunit-fixture a[ rel = 'bookmark' ]", [ "simon1" ] );
  126. assert.t( "Attribute Equals Number", "#qunit-fixture option[value='1']", [ "option1b", "option2b", "option3b", "option4b", "option5c" ] );
  127. assert.t( "Attribute Equals Number", "#qunit-fixture li[tabIndex='-1']", [ "foodWithNegativeTabIndex" ] );
  128. document.getElementById( "anchor2" ).href = "#2";
  129. assert.t( "href Attribute", "p a[href^='#']", [ "anchor2" ] );
  130. assert.t( "href Attribute", "p a[href*='#']", [ "simon1", "anchor2" ] );
  131. assert.t( "for Attribute", "form label[for]", [ "label-for" ] );
  132. assert.t( "for Attribute in form", "#form [for=action]", [ "label-for" ] );
  133. assert.t( "Attribute containing []", "input[name^='foo[']", [ "hidden2" ] );
  134. assert.t( "Attribute containing []", "input[name^='foo[bar]']", [ "hidden2" ] );
  135. assert.t( "Attribute containing []", "input[name*='[bar]']", [ "hidden2" ] );
  136. assert.t( "Attribute containing []", "input[name$='bar]']", [ "hidden2" ] );
  137. assert.t( "Attribute containing []", "input[name$='[bar]']", [ "hidden2" ] );
  138. assert.t( "Attribute containing []", "input[name$='foo[bar]']", [ "hidden2" ] );
  139. assert.t( "Attribute containing []", "input[name*='foo[bar]']", [ "hidden2" ] );
  140. assert.t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type='hidden']", [ "radio1", "radio2", "hidden1" ] );
  141. assert.t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=\"hidden\"]", [ "radio1", "radio2", "hidden1" ] );
  142. assert.t( "Multiple Attribute Equals", "#form input[type='radio'], #form input[type=hidden]", [ "radio1", "radio2", "hidden1" ] );
  143. assert.t( "Attribute selector using UTF8", "span[lang=中文]", [ "台北" ] );
  144. assert.t( "Attribute Begins With", "a[href ^= 'http://www']", [ "google", "yahoo" ] );
  145. assert.t( "Attribute Ends With", "a[href $= 'org/']", [ "mark" ] );
  146. assert.t( "Attribute Contains", "a[href *= 'google']", [ "google", "groups" ] );
  147. if ( jQuery.find.compile ) {
  148. assert.t( "Empty values", "#select1 option[value!='']", [ "option1b", "option1c", "option1d" ] );
  149. assert.t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", [ "google", "groups", "anchor1" ] );
  150. assert.t( "Select options via :selected", "#select1 option:selected", [ "option1a" ] );
  151. assert.t( "Select options via :selected", "#select2 option:selected", [ "option2d" ] );
  152. assert.t( "Select options via :selected", "#select3 option:selected", [ "option3b", "option3c" ] );
  153. assert.t( "Select options via :selected", "select[name='select2'] option:selected", [ "option2d" ] );
  154. } else {
  155. assert.ok( "skip", "!= not supported in selector-native" );
  156. assert.ok( "skip", "!= not supported in selector-native" );
  157. assert.ok( "skip", ":selected not supported in selector-native" );
  158. assert.ok( "skip", ":selected not supported in selector-native" );
  159. assert.ok( "skip", ":selected not supported in selector-native" );
  160. assert.ok( "skip", ":selected not supported in selector-native" );
  161. }
  162. assert.t( "Empty values", "#select1 option[value='']", [ "option1a" ] );
  163. assert.t( "Grouped Form Elements", "input[name='foo[bar]']", [ "hidden2" ] );
  164. // Make sure attribute value quoting works correctly. See jQuery #6093; #6428; #13894
  165. // Use seeded results to bypass querySelectorAll optimizations
  166. attrbad = jQuery(
  167. "<input type='hidden' id='attrbad_space' name='foo bar'/>" +
  168. "<input type='hidden' id='attrbad_dot' value='2' name='foo.baz'/>" +
  169. "<input type='hidden' id='attrbad_brackets' value='2' name='foo[baz]'/>" +
  170. "<input type='hidden' id='attrbad_injection' data-attr='foo_baz&#39;]'/>" +
  171. "<input type='hidden' id='attrbad_quote' data-attr='&#39;'/>" +
  172. "<input type='hidden' id='attrbad_backslash' data-attr='&#92;'/>" +
  173. "<input type='hidden' id='attrbad_backslash_quote' data-attr='&#92;&#39;'/>" +
  174. "<input type='hidden' id='attrbad_backslash_backslash' data-attr='&#92;&#92;'/>" +
  175. "<input type='hidden' id='attrbad_unicode' data-attr='&#x4e00;'/>"
  176. ).appendTo( "#qunit-fixture" ).get();
  177. assert.t( "Underscores don't need escaping", "input[id=types_all]", [ "types_all" ] );
  178. assert.t( "input[type=text]", "#form input[type=text]", [ "text1", "text2", "hidden2", "name" ] );
  179. assert.t( "input[type=search]", "#form input[type=search]", [ "search" ] );
  180. withScript = supportjQuery( "<div><span><script src=''/></span></div>" );
  181. assert.ok( withScript.find( "#moretests script[src]" ).has( "script" ), "script[src] (jQuery #13777)" );
  182. div = document.getElementById( "foo" );
  183. assert.t( "Object.prototype property \"constructor\" (negative)", "[constructor]", [] );
  184. assert.t( "Gecko Object.prototype property \"watch\" (negative)", "[watch]", [] );
  185. div.setAttribute( "constructor", "foo" );
  186. div.setAttribute( "watch", "bar" );
  187. assert.t( "Object.prototype property \"constructor\"", "[constructor='foo']", [ "foo" ] );
  188. assert.t( "Gecko Object.prototype property \"watch\"", "[watch='bar']", [ "foo" ] );
  189. assert.t( "Value attribute is retrieved correctly", "input[value=Test]", [ "text1", "text2" ] );
  190. if ( jQuery.find.compile ) {
  191. // #12600
  192. assert.ok(
  193. jQuery( "<select value='12600'><option value='option' selected='selected'></option><option value=''></option></select>" )
  194. .prop( "value", "option" )
  195. .is( ":input[value='12600']" ),
  196. ":input[value=foo] selects select by attribute"
  197. );
  198. assert.ok( jQuery( "<input type='text' value='12600'/>" ).prop( "value", "option" ).is( ":input[value='12600']" ),
  199. ":input[value=foo] selects text input by attribute"
  200. );
  201. } else {
  202. assert.ok( "skip", ":input not supported in selector-native" );
  203. assert.ok( "skip", ":input not supported in selector-native" );
  204. }
  205. // #11115
  206. assert.ok( jQuery( "<input type='checkbox' checked='checked'/>" ).prop( "checked", false ).is( "[checked]" ),
  207. "[checked] selects by attribute (positive)"
  208. );
  209. assert.ok( !jQuery( "<input type='checkbox'/>" ).prop( "checked", true ).is( "[checked]" ),
  210. "[checked] selects by attribute (negative)"
  211. );
  212. } );
  213. QUnit.test( "disconnected nodes", function( assert ) {
  214. assert.expect( 1 );
  215. var $div = jQuery( "<div></div>" );
  216. assert.equal( $div.is( "div" ), true, "Make sure .is('nodeName') works on disconnected nodes." );
  217. } );
  218. QUnit[ jQuery.find.compile ? "test" : "skip" ]( "disconnected nodes", function( assert ) {
  219. assert.expect( 3 );
  220. var $opt = jQuery( "<option></option>" ).attr( "value", "whipit" ).appendTo( "#qunit-fixture" ).detach();
  221. assert.equal( $opt.val(), "whipit", "option value" );
  222. assert.equal( $opt.is( ":selected" ), false, "unselected option" );
  223. $opt.prop( "selected", true );
  224. assert.equal( $opt.is( ":selected" ), true, "selected option" );
  225. } );
  226. testIframe(
  227. "attributes - jQuery.attr",
  228. "selector/html5_selector.html",
  229. function( assert, jQuery, window, document ) {
  230. assert.expect( 38 );
  231. /**
  232. * Returns an array of elements with the given IDs
  233. * q & t are added here for the iFrame's context
  234. */
  235. function q() {
  236. var r = [],
  237. i = 0;
  238. for ( ; i < arguments.length; i++ ) {
  239. r.push( document.getElementById( arguments[ i ] ) );
  240. }
  241. return r;
  242. }
  243. /**
  244. * Asserts that a select matches the given IDs
  245. * @example t("Check for something", "//[a]", ["foo", "bar"]);
  246. * @param {String} a - Assertion name
  247. * @param {String} b - Sizzle selector
  248. * @param {Array} c - Array of ids to construct what is expected
  249. */
  250. function t( a, b, c ) {
  251. var f = jQuery( b ).get(),
  252. s = "",
  253. i = 0;
  254. for ( ; i < f.length; i++ ) {
  255. s += ( s && "," ) + "'" + f[ i ].id + "'";
  256. }
  257. assert.deepEqual( f, q.apply( q, c ), a + " (" + b + ")" );
  258. }
  259. // ====== All known boolean attributes, including html5 booleans ======
  260. // autobuffer, autofocus, autoplay, async, checked,
  261. // compact, controls, declare, defer, disabled,
  262. // formnovalidate, hidden, indeterminate (property only),
  263. // ismap, itemscope, loop, multiple, muted, nohref, noresize,
  264. // noshade, nowrap, novalidate, open, pubdate, readonly, required,
  265. // reversed, scoped, seamless, selected, truespeed, visible (skipping visible attribute, which is on a barprop object)
  266. t( "Attribute Exists", "[autobuffer]", [ "video1" ] );
  267. t( "Attribute Exists", "[autofocus]", [ "text1" ] );
  268. t( "Attribute Exists", "[autoplay]", [ "video1" ] );
  269. t( "Attribute Exists", "[async]", [ "script1" ] );
  270. t( "Attribute Exists", "[checked]", [ "check1" ] );
  271. t( "Attribute Exists", "[compact]", [ "dl" ] );
  272. t( "Attribute Exists", "[controls]", [ "video1" ] );
  273. t( "Attribute Exists", "[declare]", [ "object1" ] );
  274. t( "Attribute Exists", "[defer]", [ "script1" ] );
  275. t( "Attribute Exists", "[disabled]", [ "check1" ] );
  276. t( "Attribute Exists", "[formnovalidate]", [ "form1" ] );
  277. t( "Attribute Exists", "[hidden]", [ "div1" ] );
  278. t( "Attribute Exists", "[indeterminate]", [] );
  279. t( "Attribute Exists", "[ismap]", [ "img1" ] );
  280. t( "Attribute Exists", "[itemscope]", [ "div1" ] );
  281. t( "Attribute Exists", "[loop]", [ "video1" ] );
  282. t( "Attribute Exists", "[multiple]", [ "select1" ] );
  283. t( "Attribute Exists", "[muted]", [ "audio1" ] );
  284. t( "Attribute Exists", "[nohref]", [ "area1" ] );
  285. t( "Attribute Exists", "[noresize]", [ "textarea1" ] );
  286. t( "Attribute Exists", "[noshade]", [ "hr1" ] );
  287. t( "Attribute Exists", "[nowrap]", [ "td1", "div1" ] );
  288. t( "Attribute Exists", "[novalidate]", [ "form1" ] );
  289. t( "Attribute Exists", "[open]", [ "details1" ] );
  290. t( "Attribute Exists", "[pubdate]", [ "article1" ] );
  291. t( "Attribute Exists", "[readonly]", [ "text1" ] );
  292. t( "Attribute Exists", "[required]", [ "text1" ] );
  293. t( "Attribute Exists", "[reversed]", [ "ol1" ] );
  294. t( "Attribute Exists", "[scoped]", [ "style1" ] );
  295. t( "Attribute Exists", "[seamless]", [ "iframe1" ] );
  296. t( "Attribute Exists", "[selected]", [ "option1" ] );
  297. t( "Attribute Exists", "[truespeed]", [ "marquee1" ] );
  298. // Enumerated attributes (these are not boolean content attributes)
  299. jQuery.expandedEach = jQuery.each;
  300. jQuery.expandedEach( [ "draggable", "contenteditable", "aria-disabled" ], function( i, val ) {
  301. t( "Enumerated attribute", "[" + val + "]", [ "div1" ] );
  302. } );
  303. t( "Enumerated attribute", "[spellcheck]", [ "span1" ] );
  304. t( "tabindex selector does not retrieve all elements in IE6/7 (#8473)",
  305. "form, [tabindex]", [ "form1", "text1" ] );
  306. t( "Improperly named form elements do not interfere with form selections (#9570)", "form[name='formName']", [ "form1" ] );
  307. }
  308. );
  309. QUnit.test( "jQuery.contains", function( assert ) {
  310. assert.expect( 16 );
  311. var container = document.getElementById( "nonnodes" ),
  312. element = container.firstChild,
  313. text = element.nextSibling,
  314. nonContained = container.nextSibling,
  315. detached = document.createElement( "a" );
  316. assert.ok( element && element.nodeType === 1, "preliminary: found element" );
  317. assert.ok( text && text.nodeType === 3, "preliminary: found text" );
  318. assert.ok( nonContained, "preliminary: found non-descendant" );
  319. assert.ok( jQuery.contains( container, element ), "child" );
  320. assert.ok( jQuery.contains( container.parentNode, element ), "grandchild" );
  321. assert.ok( jQuery.contains( container, text ), "text child" );
  322. assert.ok( jQuery.contains( container.parentNode, text ), "text grandchild" );
  323. assert.ok( !jQuery.contains( container, container ), "self" );
  324. assert.ok( !jQuery.contains( element, container ), "parent" );
  325. assert.ok( !jQuery.contains( container, nonContained ), "non-descendant" );
  326. assert.ok( !jQuery.contains( container, document ), "document" );
  327. assert.ok( !jQuery.contains( container, document.documentElement ), "documentElement (negative)" );
  328. assert.ok( !jQuery.contains( container, null ), "Passing null does not throw an error" );
  329. assert.ok( jQuery.contains( document, document.documentElement ), "documentElement (positive)" );
  330. assert.ok( jQuery.contains( document, element ), "document container (positive)" );
  331. assert.ok( !jQuery.contains( document, detached ), "document container (negative)" );
  332. } );
  333. QUnit.test( "jQuery.uniqueSort", function( assert ) {
  334. assert.expect( 15 );
  335. function Arrayish( arr ) {
  336. var i = this.length = arr.length;
  337. while ( i-- ) {
  338. this[ i ] = arr[ i ];
  339. }
  340. }
  341. Arrayish.prototype = {
  342. slice: [].slice,
  343. sort: [].sort,
  344. splice: [].splice
  345. };
  346. var i, tests,
  347. detached = [],
  348. body = document.body,
  349. fixture = document.getElementById( "qunit-fixture" ),
  350. detached1 = document.createElement( "p" ),
  351. detached2 = document.createElement( "ul" ),
  352. detachedChild = detached1.appendChild( document.createElement( "a" ) ),
  353. detachedGrandchild = detachedChild.appendChild( document.createElement( "b" ) );
  354. for ( i = 0; i < 12; i++ ) {
  355. detached.push( document.createElement( "li" ) );
  356. detached[ i ].id = "detached" + i;
  357. detached2.appendChild( document.createElement( "li" ) ).id = "detachedChild" + i;
  358. }
  359. tests = {
  360. "Empty": {
  361. input: [],
  362. expected: []
  363. },
  364. "Single-element": {
  365. input: [ fixture ],
  366. expected: [ fixture ]
  367. },
  368. "No duplicates": {
  369. input: [ fixture, body ],
  370. expected: [ body, fixture ]
  371. },
  372. "Duplicates": {
  373. input: [ body, fixture, fixture, body ],
  374. expected: [ body, fixture ]
  375. },
  376. "Detached": {
  377. input: detached.slice( 0 ),
  378. expected: detached.slice( 0 )
  379. },
  380. "Detached children": {
  381. input: [
  382. detached2.childNodes[ 0 ],
  383. detached2.childNodes[ 1 ],
  384. detached2.childNodes[ 2 ],
  385. detached2.childNodes[ 3 ]
  386. ],
  387. expected: [
  388. detached2.childNodes[ 0 ],
  389. detached2.childNodes[ 1 ],
  390. detached2.childNodes[ 2 ],
  391. detached2.childNodes[ 3 ]
  392. ]
  393. },
  394. "Attached/detached mixture": {
  395. input: [ detached1, fixture, detached2, document, detachedChild, body, detachedGrandchild ],
  396. expected: [ document, body, fixture ],
  397. length: 3
  398. }
  399. };
  400. jQuery.each( tests, function( label, test ) {
  401. var length = test.length || test.input.length;
  402. assert.deepEqual( jQuery.uniqueSort( test.input ).slice( 0, length ), test.expected, label + " (array)" );
  403. assert.deepEqual( jQuery.uniqueSort( new Arrayish( test.input ) ).slice( 0, length ), test.expected, label + " (quasi-array)" );
  404. } );
  405. assert.strictEqual( jQuery.unique, jQuery.uniqueSort, "jQuery.unique() is an alias for jQuery.uniqueSort()" );
  406. } );
  407. testIframe(
  408. "Sizzle cache collides with multiple Sizzles on a page",
  409. "selector/sizzle_cache.html",
  410. function( assert, jQuery, window, document ) {
  411. var $cached = window.$cached;
  412. assert.expect( 4 );
  413. assert.notStrictEqual( jQuery, $cached, "Loaded two engines" );
  414. assert.deepEqual( $cached( ".test a" ).get(), [ document.getElementById( "collision" ) ], "Select collision anchor with first sizzle" );
  415. assert.equal( jQuery( ".evil a" ).length, 0, "Select nothing with second sizzle" );
  416. assert.equal( jQuery( ".evil a" ).length, 0, "Select nothing again with second sizzle" );
  417. }
  418. );
  419. QUnit.test( "Iframe dispatch should not affect jQuery (#13936)", function( assert ) {
  420. assert.expect( 1 );
  421. var loaded = false,
  422. thrown = false,
  423. iframe = document.getElementById( "iframe" ),
  424. iframeDoc = iframe.contentDocument || iframe.contentWindow.document,
  425. done = assert.async();
  426. jQuery( iframe ).on( "load", function() {
  427. var form;
  428. try {
  429. iframeDoc = this.contentDocument || this.contentWindow.document;
  430. form = jQuery( "#navigate", iframeDoc )[ 0 ];
  431. } catch ( e ) {
  432. thrown = e;
  433. }
  434. if ( loaded ) {
  435. assert.strictEqual( thrown, false, "No error thrown from post-reload jQuery call" );
  436. // clean up
  437. jQuery( iframe ).off();
  438. done();
  439. } else {
  440. loaded = true;
  441. form.submit();
  442. }
  443. } );
  444. iframeDoc.open();
  445. iframeDoc.write( "<body><form id='navigate' action='?'></form></body>" );
  446. iframeDoc.close();
  447. } );
  448. QUnit.test( "Ensure escapeSelector exists (escape tests in Sizzle)", function( assert ) {
  449. assert.expect( 1 );
  450. assert.equal( jQuery.escapeSelector( "#foo.bar" ), "\\#foo\\.bar", "escapeSelector present" );
  451. } );