2012-12-13 01:19:18 +00:00
module ( "selector" , { teardown : moduleTeardown } ) ;
2012-05-29 16:40:13 +00:00
2011-09-12 23:40:14 +00:00
/ * *
2012-05-28 16:18:40 +00:00
* This test page is for selector tests that require jQuery in order to do the selection
2011-09-12 23:40:14 +00:00
* /
2012-05-28 16:18:40 +00:00
test ( "element - jQuery only" , function ( ) {
2012-05-28 18:35:01 +00:00
expect ( 7 ) ;
2012-05-28 16:18:40 +00:00
2012-12-11 00:07:07 +00:00
var fixture = document . getElementById ( "qunit-fixture" ) ;
deepEqual ( jQuery ( "p" , fixture ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a Node context." ) ;
deepEqual ( jQuery ( "p" , "#qunit-fixture" ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a selector context." ) ;
deepEqual ( jQuery ( "p" , jQuery ( "#qunit-fixture" ) ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a jQuery object context." ) ;
deepEqual ( jQuery ( "#qunit-fixture" ) . find ( "p" ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a context via .find()." ) ;
2012-05-28 16:18:40 +00:00
2012-06-21 19:30:24 +00:00
ok ( jQuery ( "#length" ) . length , "<input name=\"length\"> cannot be found under IE, see #945" ) ;
ok ( jQuery ( "#lengthtest input" ) . length , "<input name=\"length\"> cannot be found under IE, see #945" ) ;
2012-05-28 18:35:01 +00:00
2012-06-20 15:19:24 +00:00
// #7533
2012-05-28 16:18:40 +00:00
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" ) ;
} ) ;
2014-02-24 18:05:16 +00:00
test ( "id" , function ( ) {
expect ( 26 ) ;
var a ;
t ( "ID Selector" , "#body" , [ "body" ] ) ;
t ( "ID Selector w/ Element" , "body#body" , [ "body" ] ) ;
t ( "ID Selector w/ Element" , "ul#first" , [ ] ) ;
t ( "ID selector with existing ID descendant" , "#firstp #simon1" , [ "simon1" ] ) ;
t ( "ID selector with non-existant descendant" , "#firstp #foobar" , [ ] ) ;
t ( "ID selector using UTF8" , "#台北Táiběi" , [ "台北Táiběi" ] ) ;
t ( "Multiple ID selectors using UTF8" , "#台北Táiběi, #台北" , [ "台北Táiběi" , "台北" ] ) ;
t ( "Descendant ID selector using UTF8" , "div #台北" , [ "台北" ] ) ;
t ( "Child ID selector using UTF8" , "form > #台北" , [ "台北" ] ) ;
t ( "Escaped ID" , "#foo\\:bar" , [ "foo:bar" ] ) ;
t ( "Escaped ID" , "#test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
t ( "Descendant escaped ID" , "div #foo\\:bar" , [ "foo:bar" ] ) ;
t ( "Descendant escaped ID" , "div #test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
t ( "Child escaped ID" , "form > #foo\\:bar" , [ "foo:bar" ] ) ;
t ( "Child escaped ID" , "form > #test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
t ( "ID Selector, child ID present" , "#form > #radio1" , [ "radio1" ] ) ; // bug #267
t ( "ID Selector, not an ancestor ID" , "#form #first" , [ ] ) ;
t ( "ID Selector, not a child ID" , "#form > #option1a" , [ ] ) ;
t ( "All Children of ID" , "#foo > *" , [ "sndp" , "en" , "sap" ] ) ;
t ( "All Children of ID with no children" , "#firstUL > *" , [ ] ) ;
a = jQuery ( "<a id='backslash\\foo'></a>" ) . appendTo ( "#qunit-fixture" ) ;
t ( "ID Selector contains backslash" , "#backslash\\\\foo" , [ "backslash\\foo" ] ) ;
t ( "ID Selector on Form with an input that has a name of 'id'" , "#lengthtest" , [ "lengthtest" ] ) ;
t ( "ID selector with non-existant ancestor" , "#asdfasdf #foobar" , [ ] ) ; // bug #986
t ( "Underscore ID" , "#types_all" , [ "types_all" ] ) ;
t ( "Dash ID" , "#qunit-fixture" , [ "qunit-fixture" ] ) ;
t ( "ID with weird characters in it" , "#name\\+value" , [ "name+value" ] ) ;
} ) ;
2012-05-28 16:18:40 +00:00
test ( "class - jQuery only" , function ( ) {
expect ( 4 ) ;
deepEqual ( jQuery ( ".blog" , document . getElementsByTagName ( "p" ) ) . get ( ) , q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
deepEqual ( jQuery ( ".blog" , "p" ) . get ( ) , q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
deepEqual ( jQuery ( ".blog" , jQuery ( "p" ) ) . get ( ) , q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
deepEqual ( jQuery ( "p" ) . find ( ".blog" ) . get ( ) , q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
} ) ;
2014-02-24 18:05:16 +00:00
test ( "name" , function ( ) {
expect ( 5 ) ;
var form ;
t ( "Name selector" , "input[name=action]" , [ "text1" ] ) ;
t ( "Name selector with single quotes" , "input[name='action']" , [ "text1" ] ) ;
t ( "Name selector with double quotes" , "input[name=\"action\"]" , [ "text1" ] ) ;
t ( "Name selector for grouped input" , "input[name='types[]']" , [ "types_all" , "types_anime" , "types_movie" ] ) ;
form = jQuery ( "<form><input name='id'/></form>" ) . appendTo ( "body" ) ;
equal ( jQuery ( "input" , form [ 0 ] ) . length , 1 , "Make sure that rooted queries on forms (with possible expandos) work." ) ;
form . remove ( ) ;
} ) ;
2014-02-26 23:13:26 +00:00
test ( "comma selectors" , function ( ) {
expect ( 4 ) ;
var fixture = jQuery ( "<div><h2><span/></h2><div><p><span/></p><p/></div></div>" ) ;
equal ( fixture . find ( "h2, div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
equal ( fixture . find ( "h2, div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
equal ( fixture . find ( "h2 , div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
equal ( fixture . find ( "h2 , div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
} ) ;
2012-05-30 17:46:50 +00:00
test ( "attributes - jQuery only" , function ( ) {
2013-03-27 01:20:27 +00:00
expect ( 5 ) ;
2012-05-30 17:46:50 +00:00
t ( "Find elements with a tabindex attribute" , "[tabindex]" , [ "listWithTabIndex" , "foodWithNegativeTabIndex" , "linkWithTabIndex" , "linkWithNegativeTabIndex" , "linkWithNoHrefWithTabIndex" , "linkWithNoHrefWithNegativeTabIndex" ] ) ;
2012-12-08 21:28:10 +00:00
// #12600
ok (
jQuery ( "<select value='12600'><option value='option' selected='selected'></option><option value=''></option></select>" )
. prop ( "value" , "option" )
. is ( ":input[value='12600']" ) ,
":input[value=foo] selects select by attribute"
) ;
ok ( jQuery ( "<input type='text' value='12600'/>" ) . prop ( "value" , "option" ) . is ( ":input[value='12600']" ) ,
":input[value=foo] selects text input by attribute"
) ;
2012-12-09 05:26:24 +00:00
// #11115
ok ( jQuery ( "<input type='checkbox' checked='checked'/>" ) . prop ( "checked" , false ) . is ( "[checked]" ) ,
"[checked] selects by attribute (positive)"
) ;
ok ( ! jQuery ( "<input type='checkbox'/>" ) . prop ( "checked" , true ) . is ( "[checked]" ) ,
"[checked] selects by attribute (negative)"
) ;
2012-05-30 17:46:50 +00:00
} ) ;
2012-05-28 16:18:40 +00:00
test ( "disconnected nodes" , function ( ) {
2013-02-19 04:52:29 +00:00
expect ( 1 ) ;
var $div = jQuery ( "<div/>" ) ;
equal ( $div . is ( "div" ) , true , "Make sure .is('nodeName') works on disconnected nodes." ) ;
} ) ;
test ( "disconnected nodes - jQuery only" , function ( ) {
expect ( 3 ) ;
2012-10-16 14:17:14 +00:00
var $opt = jQuery ( "<option></option>" ) . attr ( "value" , "whipit" ) . appendTo ( "#qunit-fixture" ) . detach ( ) ;
2012-05-28 16:18:40 +00:00
equal ( $opt . val ( ) , "whipit" , "option value" ) ;
equal ( $opt . is ( ":selected" ) , false , "unselected option" ) ;
2012-12-09 05:26:24 +00:00
$opt . prop ( "selected" , true ) ;
2012-05-28 16:18:40 +00:00
equal ( $opt . is ( ":selected" ) , true , "selected option" ) ;
} ) ;
2012-02-23 20:48:12 +00:00
testIframe ( "selector/html5_selector" , "attributes - jQuery.attr" , function ( jQuery , window , document ) {
2012-05-30 18:16:27 +00:00
expect ( 35 ) ;
2011-09-12 23:40:14 +00:00
/ * *
2012-05-29 16:40:13 +00:00
* Returns an array of elements with the given IDs
* q & t are added here for the iFrame ' s context
2011-09-12 23:40:14 +00:00
* /
2011-10-13 15:11:41 +00:00
function q ( ) {
var r = [ ] ,
i = 0 ;
for ( ; i < arguments . length ; i ++ ) {
r . push ( document . getElementById ( arguments [ i ] ) ) ;
}
return r ;
}
2012-02-23 20:48:12 +00:00
2011-09-12 23:40:14 +00:00
/ * *
2012-05-28 16:43:41 +00:00
* Asserts that a select matches the given IDs
* @ example t ( "Check for something" , "//[a]" , [ "foo" , "baar" ] ) ;
2011-09-12 23:40:14 +00:00
* @ param { String } a - Assertion name
* @ param { String } b - Sizzle selector
2012-07-05 19:52:13 +00:00
* @ param { Array } c - Array of ids to construct what is expected
2011-09-12 23:40:14 +00:00
* /
2011-10-13 15:11:41 +00:00
function t ( a , b , c ) {
var f = jQuery ( b ) . get ( ) ,
s = "" ,
i = 0 ;
2012-02-23 20:48:12 +00:00
2011-10-13 15:11:41 +00:00
for ( ; i < f . length ; i ++ ) {
2012-10-16 14:17:14 +00:00
s += ( s && "," ) + "'" + f [ i ] . id + "'" ;
2011-09-12 23:40:14 +00:00
}
deepEqual ( f , q . apply ( q , c ) , a + " (" + b + ")" ) ;
2011-10-13 15:11:41 +00:00
}
2011-09-12 23:40:14 +00:00
// ====== All known boolean attributes, including html5 booleans ======
// autobuffer, autofocus, autoplay, async, checked,
// compact, controls, declare, defer, disabled,
// formnovalidate, hidden, indeterminate (property only),
// ismap, itemscope, loop, multiple, muted, nohref, noresize,
// noshade, nowrap, novalidate, open, pubdate, readonly, required,
// reversed, scoped, seamless, selected, truespeed, visible (skipping visible attribute, which is on a barprop object)
t ( "Attribute Exists" , "[autobuffer]" , [ "video1" ] ) ;
t ( "Attribute Exists" , "[autofocus]" , [ "text1" ] ) ;
t ( "Attribute Exists" , "[autoplay]" , [ "video1" ] ) ;
t ( "Attribute Exists" , "[async]" , [ "script1" ] ) ;
t ( "Attribute Exists" , "[checked]" , [ "check1" ] ) ;
t ( "Attribute Exists" , "[compact]" , [ "dl" ] ) ;
t ( "Attribute Exists" , "[controls]" , [ "video1" ] ) ;
t ( "Attribute Exists" , "[declare]" , [ "object1" ] ) ;
t ( "Attribute Exists" , "[defer]" , [ "script1" ] ) ;
t ( "Attribute Exists" , "[disabled]" , [ "check1" ] ) ;
t ( "Attribute Exists" , "[formnovalidate]" , [ "form1" ] ) ;
t ( "Attribute Exists" , "[hidden]" , [ "div1" ] ) ;
t ( "Attribute Exists" , "[indeterminate]" , [ ] ) ;
t ( "Attribute Exists" , "[ismap]" , [ "img1" ] ) ;
t ( "Attribute Exists" , "[itemscope]" , [ "div1" ] ) ;
2012-05-28 22:32:00 +00:00
// t( "Attribute Exists", "[loop]", ["video1"]); // IE 6/7 cannot differentiate here. loop is also used on img, input, and marquee tags as well as video/audio. getAttributeNode unfortunately also retrieves the property value.
2011-09-12 23:40:14 +00:00
t ( "Attribute Exists" , "[multiple]" , [ "select1" ] ) ;
t ( "Attribute Exists" , "[muted]" , [ "audio1" ] ) ;
// t( "Attribute Exists", "[nohref]", ["area1"]); // IE 6/7 keep this set to false regardless of presence. The attribute node is not retrievable.
t ( "Attribute Exists" , "[noresize]" , [ "textarea1" ] ) ;
t ( "Attribute Exists" , "[noshade]" , [ "hr1" ] ) ;
t ( "Attribute Exists" , "[nowrap]" , [ "td1" , "div1" ] ) ;
t ( "Attribute Exists" , "[novalidate]" , [ "form1" ] ) ;
t ( "Attribute Exists" , "[open]" , [ "details1" ] ) ;
t ( "Attribute Exists" , "[pubdate]" , [ "article1" ] ) ;
t ( "Attribute Exists" , "[readonly]" , [ "text1" ] ) ;
t ( "Attribute Exists" , "[required]" , [ "text1" ] ) ;
t ( "Attribute Exists" , "[reversed]" , [ "ol1" ] ) ;
t ( "Attribute Exists" , "[scoped]" , [ "style1" ] ) ;
t ( "Attribute Exists" , "[seamless]" , [ "iframe1" ] ) ;
2012-05-28 22:32:00 +00:00
t ( "Attribute Exists" , "[selected]" , [ "option1" ] ) ;
2011-09-12 23:40:14 +00:00
t ( "Attribute Exists" , "[truespeed]" , [ "marquee1" ] ) ;
// Enumerated attributes (these are not boolean content attributes)
2012-07-05 19:52:13 +00:00
jQuery . expandedEach = jQuery . each ;
jQuery . expandedEach ( [ "draggable" , "contenteditable" , "aria-disabled" ] , function ( i , val ) {
2011-09-12 23:40:14 +00:00
t ( "Enumerated attribute" , "[" + val + "]" , [ "div1" ] ) ;
} ) ;
t ( "Enumerated attribute" , "[spellcheck]" , [ "span1" ] ) ;
2012-05-30 18:16:27 +00:00
// t( "tabindex selector does not retrieve all elements in IE6/7(#8473)", "form, [tabindex]", ["form1", "text1"] ); // sigh, FF12 QSA mistakenly includes video elements even though they have no tabindex attribute (see https://bugzilla.mozilla.org/show_bug.cgi?id=618737)
2012-05-30 18:07:59 +00:00
t ( "Improperly named form elements do not interfere with form selections (#9570)" , "form[name='formName']" , [ "form1" ] ) ;
2011-09-12 23:40:14 +00:00
} ) ;
2011-10-13 15:11:41 +00:00
2014-02-26 23:01:07 +00:00
test ( "jQuery.contains" , function ( ) {
expect ( 16 ) ;
var container = document . getElementById ( "nonnodes" ) ,
element = container . firstChild ,
text = element . nextSibling ,
nonContained = container . nextSibling ,
detached = document . createElement ( "a" ) ;
ok ( element && element . nodeType === 1 , "preliminary: found element" ) ;
ok ( text && text . nodeType === 3 , "preliminary: found text" ) ;
ok ( nonContained , "preliminary: found non-descendant" ) ;
ok ( jQuery . contains ( container , element ) , "child" ) ;
ok ( jQuery . contains ( container . parentNode , element ) , "grandchild" ) ;
ok ( jQuery . contains ( container , text ) , "text child" ) ;
ok ( jQuery . contains ( container . parentNode , text ) , "text grandchild" ) ;
ok ( ! jQuery . contains ( container , container ) , "self" ) ;
ok ( ! jQuery . contains ( element , container ) , "parent" ) ;
ok ( ! jQuery . contains ( container , nonContained ) , "non-descendant" ) ;
ok ( ! jQuery . contains ( container , document ) , "document" ) ;
ok ( ! jQuery . contains ( container , document . documentElement ) , "documentElement (negative)" ) ;
ok ( ! jQuery . contains ( container , null ) , "Passing null does not throw an error" ) ;
ok ( jQuery . contains ( document , document . documentElement ) , "documentElement (positive)" ) ;
ok ( jQuery . contains ( document , element ) , "document container (positive)" ) ;
ok ( ! jQuery . contains ( document , detached ) , "document container (negative)" ) ;
} ) ;
2014-02-26 23:01:48 +00:00
test ( "jQuery.unique" , function ( ) {
expect ( 14 ) ;
function Arrayish ( arr ) {
var i = this . length = arr . length ;
while ( i -- ) {
this [ i ] = arr [ i ] ;
}
}
Arrayish . prototype = {
slice : [ ] . slice ,
sort : [ ] . sort ,
splice : [ ] . splice
} ;
var i , tests ,
detached = [ ] ,
body = document . body ,
fixture = document . getElementById ( "qunit-fixture" ) ,
detached1 = document . createElement ( "p" ) ,
detached2 = document . createElement ( "ul" ) ,
detachedChild = detached1 . appendChild ( document . createElement ( "a" ) ) ,
detachedGrandchild = detachedChild . appendChild ( document . createElement ( "b" ) ) ;
for ( i = 0 ; i < 12 ; i ++ ) {
detached . push ( document . createElement ( "li" ) ) ;
detached [ i ] . id = "detached" + i ;
detached2 . appendChild ( document . createElement ( "li" ) ) . id = "detachedChild" + i ;
}
tests = {
"Empty" : {
input : [ ] ,
expected : [ ]
} ,
"Single-element" : {
input : [ fixture ] ,
expected : [ fixture ]
} ,
"No duplicates" : {
input : [ fixture , body ] ,
expected : [ body , fixture ]
} ,
"Duplicates" : {
input : [ body , fixture , fixture , body ] ,
expected : [ body , fixture ]
} ,
"Detached" : {
input : detached . slice ( 0 ) ,
expected : detached . slice ( 0 )
} ,
"Detached children" : {
input : [
detached2 . childNodes [ 0 ] ,
detached2 . childNodes [ 1 ] ,
detached2 . childNodes [ 2 ] ,
detached2 . childNodes [ 3 ]
] ,
expected : [
detached2 . childNodes [ 0 ] ,
detached2 . childNodes [ 1 ] ,
detached2 . childNodes [ 2 ] ,
detached2 . childNodes [ 3 ]
]
} ,
"Attached/detached mixture" : {
input : [ detached1 , fixture , detached2 , document , detachedChild , body , detachedGrandchild ] ,
expected : [ document , body , fixture ] ,
length : 3
}
} ;
jQuery . each ( tests , function ( label , test ) {
var length = test . length || test . input . length ;
deepEqual ( jQuery . unique ( test . input ) . slice ( 0 , length ) , test . expected , label + " (array)" ) ;
deepEqual ( jQuery . unique ( new Arrayish ( test . input ) ) . slice ( 0 , length ) , test . expected , label + " (quasi-array)" ) ;
} ) ;
} ) ;
2012-02-23 20:48:12 +00:00
testIframe ( "selector/sizzle_cache" , "Sizzle cache collides with multiple Sizzles on a page" , function ( jQuery , window , document ) {
2012-07-05 19:52:13 +00:00
var $cached = window [ "$cached" ] ;
2011-10-13 15:11:41 +00:00
2013-02-08 05:20:33 +00:00
expect ( 4 ) ;
notStrictEqual ( jQuery , $cached , "Loaded two engines" ) ;
2012-10-16 14:17:14 +00:00
deepEqual ( $cached ( ".test a" ) . get ( ) , [ document . getElementById ( "collision" ) ] , "Select collision anchor with first sizzle" ) ;
equal ( jQuery ( ".evil a" ) . length , 0 , "Select nothing with second sizzle" ) ;
equal ( jQuery ( ".evil a" ) . length , 0 , "Select nothing again with second sizzle" ) ;
2011-10-13 15:11:41 +00:00
} ) ;
2014-02-24 18:05:16 +00:00
asyncTest ( "Iframe dispatch should not affect Sizzle, see #13936" , 1 , function ( ) {
var loaded = false ,
thrown = false ,
iframe = document . getElementById ( "iframe" ) ,
iframeDoc = iframe . contentDocument || iframe . contentWindow . document ;
jQuery ( iframe ) . on ( "load" , function ( ) {
var form ;
try {
iframeDoc = this . contentDocument || this . contentWindow . document ;
form = jQuery ( "#navigate" , iframeDoc ) [ 0 ] ;
} catch ( e ) {
thrown = e ;
}
if ( loaded ) {
strictEqual ( thrown , false , "No error thrown from post-reload jQuery call" ) ;
// clean up
jQuery ( iframe ) . off ( ) ;
start ( ) ;
} else {
loaded = true ;
form . submit ( ) ;
}
} ) ;
iframeDoc . open ( ) ;
iframeDoc . write ( "<body><form id='navigate'></form></body>" ) ;
iframeDoc . close ( ) ;
} ) ;