2019-06-26 19:39:10 +00:00
QUnit . module ( "selector" , {
beforeEach : function ( ) {
2023-01-23 22:49:44 +00:00
// Playwright WebKit on macOS doesn't expose `Safari` in its user agent
// string; use the "AppleWebKit" token. This token is also present
// in the Chromium UA, but it is locked to an older version there.
// Modern WebKit (Safari 13+) locks it to `605.1.15`.
this . safari = /\bapplewebkit\/605\.1\.15\b/i . test ( navigator . userAgent ) ;
2019-06-26 19:39:10 +00:00
} ,
afterEach : moduleTeardown
} ) ;
QUnit . test ( "empty" , function ( assert ) {
assert . expect ( 5 ) ;
var form ;
2019-10-21 17:02:22 +00:00
assert . strictEqual ( jQuery ( "" ) . length , 0 ,
2019-06-26 19:39:10 +00:00
"Empty selector returns an empty array" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "div" , document . createTextNode ( "" ) ) . get ( ) , [ ] ,
2019-06-26 19:39:10 +00:00
"Text element as context fails silently" ) ;
form = document . getElementById ( "form" ) ;
assert . ok ( ! jQuery ( form ) . is ( "" ) , "Empty string passed to .is() does not match" ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( " " ) . length , 0 , "Empty selector returns an empty array" ) ;
assert . equal ( jQuery ( "\t" ) . length , 0 , "Empty selector returns an empty array" ) ;
2019-06-26 19:39:10 +00:00
} else {
assert . ok ( "skip" , "whitespace-only selector not supported in selector-native" ) ;
assert . ok ( "skip" , "whitespace-only selector not supported in selector-native" ) ;
}
} ) ;
QUnit . test ( "star" , function ( assert ) {
assert . expect ( 2 ) ;
2012-05-29 16:40:13 +00:00
2019-06-26 19:39:10 +00:00
var good , i ;
2019-10-21 17:02:22 +00:00
var all = jQuery ( "*" ) ;
2019-06-26 19:39:10 +00:00
assert . ok ( all . length >= 30 , "Select all" ) ;
good = true ;
for ( i = 0 ; i < all . length ; i ++ ) {
if ( all [ i ] . nodeType === 8 ) {
good = false ;
}
}
assert . ok ( good , "Select all elements, no comment nodes" ) ;
} ) ;
2011-09-12 23:40:14 +00:00
2015-11-10 18:26:15 +00:00
QUnit . test ( "element" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 37 ) ;
2012-05-28 16:18:40 +00:00
2019-06-26 19:39:10 +00:00
var i , lengthtest , siblingTest , html ;
2015-08-16 06:59:58 +00:00
var fixture = document . getElementById ( "qunit-fixture" ) ;
2012-12-11 00:07:07 +00:00
2015-08-16 06:59:58 +00:00
assert . deepEqual ( jQuery ( "p" , fixture ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a Node context." ) ;
assert . deepEqual ( jQuery ( "p" , "#qunit-fixture" ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a selector context." ) ;
assert . deepEqual ( jQuery ( "p" , jQuery ( "#qunit-fixture" ) ) . get ( ) , q ( "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ) , "Finding elements with a jQuery object context." ) ;
assert . 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
2022-01-04 15:27:18 +00:00
assert . ok ( jQuery ( "#length" ) . length , "<input name=\"length\"> cannot be found under IE, see trac-945" ) ;
assert . ok ( jQuery ( "#lengthtest input" ) . length , "<input name=\"length\"> cannot be found under IE, see trac-945" ) ;
2012-05-28 18:35:01 +00:00
2022-01-04 15:27:18 +00:00
// trac-7533
2015-08-16 06:59:58 +00:00
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" ) ;
2019-06-26 19:39:10 +00:00
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "" ) . length , 0 , "Empty selector returns an empty array" ) ;
assert . deepEqual ( jQuery ( "div" , document . createTextNode ( "" ) ) . get ( ) , [ ] ,
2019-06-26 19:39:10 +00:00
"Text element as context fails silently" ) ;
assert . t ( "Element Selector" , "html" , [ "html" ] ) ;
assert . t ( "Element Selector" , "body" , [ "body" ] ) ;
assert . t ( "Element Selector" , "#qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Leading space" , " #qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Leading tab" , "\t#qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Leading carriage return" , "\r#qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Leading line feed" , "\n#qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Leading form feed" , "\f#qunit-fixture p" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Trailing space" , "#qunit-fixture p " , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Trailing tab" , "#qunit-fixture p\t" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Trailing carriage return" , "#qunit-fixture p\r" ,
[ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Trailing line feed" , "#qunit-fixture p\n" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Trailing form feed" , "#qunit-fixture p\f" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( jQuery ( "div ol" ) ) . filter ( "#qunit-fixture *" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "empty" , "listWithTabIndex" ) ,
"Parent Element"
) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( jQuery ( "div\tol" ) ) . filter ( "#qunit-fixture *" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "empty" , "listWithTabIndex" ) ,
"Parent Element (non-space descendant combinator)"
) ;
// Check for unique-ness and sort order
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "p, div p" ) , jQuery ( "p" ) , "Check for duplicates: p, div p" ) ;
2019-06-26 19:39:10 +00:00
2020-03-16 20:49:29 +00:00
jQuery ( "<h1 id='h1'></h1><h2 id='h2'></h2><h2 id='h2-2'></h2>" ) . prependTo ( "#qunit-fixture" ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Checking sort order" , "#qunit-fixture h2, #qunit-fixture h1" , [ "h1" , "h2" , "h2-2" ] ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Checking sort order" , "#qunit-fixture h2:first, #qunit-fixture h1:first" , [ "h1" , "h2" ] ) ;
} else {
2019-07-29 19:14:46 +00:00
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
2019-06-26 19:39:10 +00:00
}
assert . t ( "Checking sort order" , "#qunit-fixture p, #qunit-fixture p a" ,
[ "firstp" , "simon1" , "ap" , "google" , "groups" , "anchor1" , "mark" , "sndp" , "en" , "yahoo" ,
"sap" , "anchor2" , "simon" , "first" ] ) ;
// Test Conflict ID
lengthtest = document . getElementById ( "lengthtest" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "#idTest" , lengthtest ) . get ( ) , q ( "idTest" ) ,
2019-06-26 19:39:10 +00:00
"Finding element with id of ID." ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "[name='id']" , lengthtest ) . get ( ) , q ( "idTest" ) ,
2019-06-26 19:39:10 +00:00
"Finding element with id of ID." ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "input[id='idTest']" , lengthtest ) . get ( ) , q ( "idTest" ) ,
2019-06-26 19:39:10 +00:00
"Finding elements with id of ID." ) ;
2023-02-13 17:34:41 +00:00
siblingTest = document . getElementById ( "siblingTest" ) ;
assert . deepEqual ( jQuery ( "div em" , siblingTest ) . get ( ) , [ ] ,
"Element-rooted QSA does not select based on document context" ) ;
assert . deepEqual ( jQuery ( "div em, div em, div em:not(div em)" , siblingTest ) . get ( ) , [ ] ,
"Element-rooted QSA does not select based on document context" ) ;
assert . deepEqual ( jQuery ( "div em, em\\," , siblingTest ) . get ( ) , [ ] ,
"Escaped commas do not get treated with an id in element-rooted QSA" ) ;
2019-06-26 19:39:10 +00:00
html = "" ;
for ( i = 0 ; i < 100 ; i ++ ) {
html = "<div>" + html + "</div>" ;
}
html = jQuery ( html ) . appendTo ( document . body ) ;
2019-10-21 17:02:22 +00:00
assert . ok ( ! ! jQuery ( "body div div div" ) . length ,
2019-06-26 19:39:10 +00:00
"No stack or performance problems with large amounts of descendants" ) ;
2019-10-21 17:02:22 +00:00
assert . ok ( ! ! jQuery ( "body>div div div" ) . length ,
2019-06-26 19:39:10 +00:00
"No stack or performance problems with large amounts of descendants" ) ;
html . remove ( ) ;
2022-01-04 15:27:18 +00:00
// Real use case would be using .watch in browsers with window.watch
// (see https://github.com/jquery/sizzle/pull/157)
2019-06-26 19:39:10 +00:00
q ( "qunit-fixture" ) [ 0 ] . appendChild ( document . createElement ( "toString" ) ) . id = "toString" ;
assert . t ( "Element name matches Object.prototype property" , "toString#toString" , [ "toString" ] ) ;
} ) ;
QUnit . test ( "XML Document Selectors" , function ( assert ) {
assert . expect ( 11 ) ;
var xml = createWithFriesXML ( ) ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "foo_bar" , xml ) . length , 1 , "Element Selector with underscore" ) ;
assert . equal ( jQuery ( ".component" , xml ) . length , 1 , "Class selector" ) ;
assert . equal ( jQuery ( "[class*=component]" , xml ) . length , 1 , "Attribute selector for class" ) ;
assert . equal ( jQuery ( "property[name=prop2]" , xml ) . length , 1 , "Attribute selector with name" ) ;
assert . equal ( jQuery ( "[name=prop2]" , xml ) . length , 1 , "Attribute selector with name" ) ;
assert . equal ( jQuery ( "#seite1" , xml ) . length , 1 , "Attribute selector with ID" ) ;
assert . equal ( jQuery ( "component#seite1" , xml ) . length , 1 , "Attribute selector with ID" ) ;
2019-06-26 19:39:10 +00:00
assert . equal ( jQuery ( "component" , xml ) . filter ( "#seite1" ) . length , 1 ,
"Attribute selector filter with ID" ) ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "meta property thing" , xml ) . length , 2 ,
2019-06-26 19:39:10 +00:00
"Descendent selector and dir caching" ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . ok ( jQuery ( xml . lastChild ) . is ( "soap\\:Envelope" ) , "Check for namespaced element" ) ;
xml = jQuery . parseXML ( "<?xml version='1.0' encoding='UTF-8'?><root><elem id='1'/></root>" ) ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "elem:not(:has(*))" , xml ) . length , 1 ,
2022-01-04 15:27:18 +00:00
"Non-qSA path correctly handles numeric ids (jQuery trac-14142)" ) ;
2019-06-26 19:39:10 +00:00
} else {
assert . ok ( "skip" , "namespaced elements not matching correctly in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
}
} ) ;
QUnit . test ( "broken selectors throw" , function ( assert ) {
2019-10-21 17:03:03 +00:00
assert . expect ( 33 ) ;
2019-06-26 19:39:10 +00:00
function broken ( name , selector ) {
assert . throws ( function ( ) {
2019-10-21 17:02:22 +00:00
jQuery ( selector ) ;
2019-06-26 19:39:10 +00:00
} , name + ": " + selector ) ;
}
broken ( "Broken Selector" , "[" ) ;
broken ( "Broken Selector" , "(" ) ;
broken ( "Broken Selector" , "{" ) ;
broken ( "Broken Selector" , "<" ) ;
broken ( "Broken Selector" , "()" ) ;
broken ( "Broken Selector" , "<>" ) ;
broken ( "Broken Selector" , "{}" ) ;
broken ( "Broken Selector" , "," ) ;
broken ( "Broken Selector" , ",a" ) ;
broken ( "Broken Selector" , "a," ) ;
2019-10-21 17:03:03 +00:00
broken ( "Post-comma invalid selector" , "*,:x" ) ;
2019-07-29 19:14:46 +00:00
broken ( "Identifier with bad escape" , "foo\\\fbaz" ) ;
2019-06-26 19:39:10 +00:00
broken ( "Broken Selector" , "[id=012345678901234567890123456789" ) ;
broken ( "Doesn't exist" , ":visble" ) ;
broken ( "Nth-child" , ":nth-child" ) ;
broken ( "Nth-child" , ":nth-child(-)" ) ;
broken ( "Nth-child" , ":nth-child(asdf)" , [ ] ) ;
broken ( "Nth-child" , ":nth-child(2n+-0)" ) ;
broken ( "Nth-child" , ":nth-child(2+0)" ) ;
broken ( "Nth-child" , ":nth-child(- 1n)" ) ;
broken ( "Nth-child" , ":nth-child(-1 n)" ) ;
broken ( "First-child" , ":first-child(n)" ) ;
broken ( "Last-child" , ":last-child(n)" ) ;
broken ( "Only-child" , ":only-child(n)" ) ;
broken ( "Nth-last-last-child" , ":nth-last-last-child(1)" ) ;
broken ( "First-last-child" , ":first-last-child" ) ;
broken ( "Last-last-child" , ":last-last-child" ) ;
broken ( "Only-last-child" , ":only-last-child" ) ;
2022-01-04 15:27:18 +00:00
// Make sure attribute value quoting works correctly. See: trac-6093
2019-06-26 19:39:10 +00:00
jQuery ( "<input type='hidden' value='2' name='foo.baz' id='attrbad1'/>" +
"<input type='hidden' value='2' name='foo[baz]' id='attrbad2'/>" )
. appendTo ( "#qunit-fixture" ) ;
broken ( "Attribute equals non-value" , "input[name=]" ) ;
2019-08-20 18:05:37 +00:00
broken ( "Attribute equals unquoted non-identifier" , "input[name=foo.baz]" ) ;
broken ( "Attribute equals unquoted non-identifier" , "input[name=foo[baz]]" ) ;
2019-06-26 19:39:10 +00:00
broken ( "Attribute equals bad string" , "input[name=''double-quoted'']" ) ;
broken ( "Attribute equals bad string" , "input[name='apostrophe'd']" ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2012-05-28 16:18:40 +00:00
2015-08-16 06:59:58 +00:00
QUnit . test ( "id" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 34 ) ;
2014-02-24 18:05:16 +00:00
2019-06-26 19:39:10 +00:00
var fiddle , a ;
2014-02-24 18:05:16 +00:00
2015-09-08 00:26:29 +00:00
assert . t ( "ID Selector" , "#body" , [ "body" ] ) ;
assert . t ( "ID Selector w/ Element" , "body#body" , [ "body" ] ) ;
assert . t ( "ID Selector w/ Element" , "ul#first" , [ ] ) ;
assert . t ( "ID selector with existing ID descendant" , "#firstp #simon1" , [ "simon1" ] ) ;
assert . t ( "ID selector with non-existent descendant" , "#firstp #foobar" , [ ] ) ;
assert . t ( "ID selector using UTF8" , "#台北Táiběi" , [ "台北Táiběi" ] ) ;
2016-05-10 09:12:28 +00:00
assert . t ( "Multiple ID selectors using UTF8" , "#台北Táiběi, #台北" , [ "台北Táiběi" , "台北" ] ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Descendant ID selector using UTF8" , "div #台北" , [ "台北" ] ) ;
assert . t ( "Child ID selector using UTF8" , "form > #台北" , [ "台北" ] ) ;
assert . t ( "Escaped ID" , "#foo\\:bar" , [ "foo:bar" ] ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Escaped ID with descendant" , "#foo\\:bar span:not(:input)" , [ "foo_descendant" ] ) ;
} else {
assert . ok ( "skip" , ":input not supported in selector-native" ) ;
}
2015-09-08 00:26:29 +00:00
assert . t ( "Escaped ID" , "#test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
assert . t ( "Descendant escaped ID" , "div #foo\\:bar" , [ "foo:bar" ] ) ;
assert . t ( "Descendant escaped ID" , "div #test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
assert . t ( "Child escaped ID" , "form > #foo\\:bar" , [ "foo:bar" ] ) ;
assert . t ( "Child escaped ID" , "form > #test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
2019-06-26 19:39:10 +00:00
fiddle = jQuery ( "<div id='fiddle\\Foo'><span id='fiddleSpan'></span></div>" )
. appendTo ( "#qunit-fixture" ) ;
2023-02-13 17:34:41 +00:00
assert . deepEqual ( jQuery ( "> span" , jQuery ( "#fiddle\\\\Foo" ) [ 0 ] ) . get ( ) ,
q ( [ "fiddleSpan" ] ) , "Escaped ID as context" ) ;
2019-06-26 19:39:10 +00:00
fiddle . remove ( ) ;
2022-01-04 15:27:18 +00:00
assert . t ( "ID Selector, child ID present" , "#form > #radio1" , [ "radio1" ] ) ; // bug trac-267
2015-09-08 00:26:29 +00:00
assert . t ( "ID Selector, not an ancestor ID" , "#form #first" , [ ] ) ;
assert . t ( "ID Selector, not a child ID" , "#form > #option1a" , [ ] ) ;
assert . t ( "All Children of ID" , "#foo > *" , [ "sndp" , "en" , "sap" ] ) ;
assert . t ( "All Children of ID with no children" , "#firstUL > *" , [ ] ) ;
2014-02-24 18:05:16 +00:00
2019-06-26 19:39:10 +00:00
assert . equal ( jQuery ( "#tName1" ) [ 0 ] . id , "tName1" ,
"ID selector with same value for a name attribute" ) ;
assert . t ( "ID selector non-existing but name attribute on an A tag" , "#tName2" , [ ] ) ;
assert . t ( "Leading ID selector non-existing but name attribute on an A tag" , "#tName2 span" , [ ] ) ;
assert . t ( "Leading ID selector existing, retrieving the child" , "#tName1 span" , [ "tName1-span" ] ) ;
assert . equal ( jQuery ( "div > div #tName1" ) [ 0 ] . id , jQuery ( "#tName1-span" ) [ 0 ] . parentNode . id ,
"Ending with ID" ) ;
2015-08-16 06:59:58 +00:00
a = jQuery ( "<a id='backslash\\foo'></a>" ) . appendTo ( "#qunit-fixture" ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "ID Selector contains backslash" , "#backslash\\\\foo" , [ "backslash\\foo" ] ) ;
2019-06-26 19:39:10 +00:00
a . remove ( ) ;
2014-02-24 18:05:16 +00:00
2015-09-08 00:26:29 +00:00
assert . t ( "ID Selector on Form with an input that has a name of 'id'" , "#lengthtest" , [ "lengthtest" ] ) ;
2014-02-24 18:05:16 +00:00
2022-01-04 15:27:18 +00:00
assert . t ( "ID selector with non-existent ancestor" , "#asdfasdf #foobar" , [ ] ) ; // bug trac-986
2014-02-24 18:05:16 +00:00
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "div#form" , document . body ) . get ( ) , [ ] ,
2019-06-26 19:39:10 +00:00
"ID selector within the context of another element" ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Underscore ID" , "#types_all" , [ "types_all" ] ) ;
assert . t ( "Dash ID" , "#qunit-fixture" , [ "qunit-fixture" ] ) ;
2014-02-24 18:05:16 +00:00
2015-09-08 00:26:29 +00:00
assert . t ( "ID with weird characters in it" , "#name\\+value" , [ "name+value" ] ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2014-02-24 18:05:16 +00:00
2015-11-10 18:26:15 +00:00
QUnit . test ( "class" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 32 ) ;
assert . deepEqual ( jQuery ( ".blog" , document . getElementsByTagName ( "p" ) ) . get ( ) ,
q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
assert . deepEqual ( jQuery ( ".blog" , "p" ) . get ( ) ,
q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
assert . deepEqual ( jQuery ( ".blog" , jQuery ( "p" ) ) . get ( ) ,
q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
assert . deepEqual ( jQuery ( "p" ) . find ( ".blog" ) . get ( ) ,
q ( "mark" , "simon" ) , "Finding elements with a context." ) ;
assert . t ( "Class Selector" , ".blog" , [ "mark" , "simon" ] ) ;
assert . t ( "Class Selector" , ".GROUPS" , [ "groups" ] ) ;
assert . t ( "Class Selector" , ".blog.link" , [ "simon" ] ) ;
assert . t ( "Class Selector w/ Element" , "a.blog" , [ "mark" , "simon" ] ) ;
assert . t ( "Parent Class Selector" , "p .blog" , [ "mark" , "simon" ] ) ;
assert . t ( "Class selector using UTF8" , ".台北Táiběi" , [ "utf8class1" ] ) ;
assert . t ( "Class selector using UTF8" , ".台北" , [ "utf8class1" , "utf8class2" ] ) ;
assert . t ( "Class selector using UTF8" , ".台北Táiběi.台北" , [ "utf8class1" ] ) ;
assert . t ( "Class selector using UTF8" , ".台北Táiběi, .台北" , [ "utf8class1" , "utf8class2" ] ) ;
assert . t ( "Descendant class selector using UTF8" , "div .台北Táiběi" , [ "utf8class1" ] ) ;
assert . t ( "Child class selector using UTF8" , "form > .台北Táiběi" , [ "utf8class1" ] ) ;
assert . t ( "Escaped Class" , ".foo\\:bar" , [ "foo:bar" ] ) ;
assert . t ( "Escaped Class" , ".test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
assert . t ( "Descendant escaped Class" , "div .foo\\:bar" , [ "foo:bar" ] ) ;
assert . t ( "Descendant escaped Class" , "div .test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
assert . t ( "Child escaped Class" , "form > .foo\\:bar" , [ "foo:bar" ] ) ;
assert . t ( "Child escaped Class" , "form > .test\\.foo\\[5\\]bar" , [ "test.foo[5]bar" ] ) ;
var div = document . createElement ( "div" ) ;
div . innerHTML = "<div class='test e'></div><div class='test'></div>" ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ".e" , div ) . get ( ) , [ div . firstChild ] , "Finding a second class." ) ;
2019-06-26 19:39:10 +00:00
div . lastChild . className = "e" ;
assert . ok ( ! jQuery ( div ) . is ( ".null" ) ,
".null does not match an element with no class" ) ;
assert . ok ( ! jQuery ( div . firstChild ) . is ( ".null div" ) ,
".null does not match an element with no class" ) ;
div . className = "null" ;
assert . ok ( jQuery ( div ) . is ( ".null" ) , ".null matches element with class 'null'" ) ;
assert . ok ( jQuery ( div . firstChild ) . is ( ".null div" ) ,
"caching system respects DOM changes" ) ;
assert . ok ( ! jQuery ( document ) . is ( ".foo" ) ,
"testing class on document doesn't error" ) ;
assert . ok ( ! jQuery ( window ) . is ( ".foo" ) , "testing class on window doesn't error" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ".e" , div ) . get ( ) , [ div . firstChild , div . lastChild ] ,
2019-06-26 19:39:10 +00:00
"Finding a modified class." ) ;
div . lastChild . className += " hasOwnProperty toString" ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ".e.hasOwnProperty.toString" , div ) . get ( ) , [ div . lastChild ] ,
2019-06-26 19:39:10 +00:00
"Classes match Object.prototype properties" ) ;
div = jQuery ( "<div><svg width='200' height='250' version='1.1'" +
" xmlns='http://www.w3.org/2000/svg'><rect x='10' y='10' width='30' height='30'" +
"class='foo'></rect></svg></div>" ) [ 0 ] ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( ".foo" , div ) . length , 1 , "Class selector against SVG container" ) ;
assert . equal ( jQuery ( ".foo" , div . firstChild ) . length , 1 ,
2019-06-26 19:39:10 +00:00
"Class selector directly against SVG" ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2012-05-28 16:18:40 +00:00
2015-08-16 06:59:58 +00:00
QUnit . test ( "name" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 14 ) ;
2014-02-24 18:05:16 +00:00
var form ;
2015-09-08 00:26:29 +00:00
assert . t ( "Name selector" , "input[name=action]" , [ "text1" ] ) ;
assert . t ( "Name selector with single quotes" , "input[name='action']" , [ "text1" ] ) ;
assert . t ( "Name selector with double quotes" , "input[name=\"action\"]" , [ "text1" ] ) ;
2014-02-24 18:05:16 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "Name selector non-input" , "[name=example]" , [ "name-is-example" ] ) ;
assert . t ( "Name selector non-input" , "[name=div]" , [ "name-is-div" ] ) ;
assert . t ( "Name selector non-input" , "*[name=iframe]" , [ "iframe" ] ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Name selector for grouped input" , "input[name='types[]']" , [ "types_all" , "types_anime" , "types_movie" ] ) ;
2014-02-24 18:05:16 +00:00
2019-06-26 19:39:10 +00:00
form = document . getElementById ( "form" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "input[name=action]" , form ) . get ( ) , q ( "text1" ) ,
2019-06-26 19:39:10 +00:00
"Name selector within the context of another element" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "input[name='foo[bar]']" , form ) . get ( ) , q ( "hidden2" ) ,
2019-06-26 19:39:10 +00:00
"Name selector for grouped form element within the context of another element" ) ;
2015-08-16 06:59:58 +00:00
form = jQuery ( "<form><input name='id'/></form>" ) . appendTo ( "body" ) ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "input" , form [ 0 ] ) . length , 1 ,
2019-06-26 19:39:10 +00:00
"Make sure that rooted queries on forms (with possible expandos) work." ) ;
2014-02-24 18:05:16 +00:00
form . remove ( ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Find elements that have similar IDs" , "[name=tName1]" , [ "tName1ID" ] ) ;
assert . t ( "Find elements that have similar IDs" , "[name=tName2]" , [ "tName2ID" ] ) ;
assert . t ( "Find elements that have similar IDs" , "#tName2ID" , [ "tName2ID" ] ) ;
assert . t ( "Case-sensitivity" , "[name=tname1]" , [ ] ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2014-02-24 18:05:16 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "comma-separated" , function ( assert ) {
Selector: Make selector lists work with `qSA` again
jQuery 3.6.2 started using `CSS.supports( "selector(SELECTOR)" )` before using
`querySelectorAll` on the selector. This was to solve gh-5098 - some selectors,
like `:has()`, now had their parameters parsed in a forgiving way, meaning
that `:has(:fakepseudo)` no longer throws but just returns 0 results, breaking
that jQuery mechanism.
A recent spec change made `CSS.supports( "selector(SELECTOR)" )` always use
non-forgiving parsing, allowing us to use this API for what we've used
`try-catch` before.
To solve the issue on the spec side for older jQuery versions, `:has()`
parameters are no longer using forgiving parsing in the latest spec update
but our new mechanism is more future-proof anyway.
However, the jQuery implementation has a bug - in
`CSS.supports( "selector(SELECTOR)" )`, `SELECTOR` needs to be
a `<complex-selector>` and not a `<complex-selector-list>`. Which means that
selector lists now skip `qSA` and go to the jQuery custom traversal:
```js
CSS.supports("selector(div:valid, span)"); // false
CSS.supports("selector(div:valid)"); // true
CSS.supports("selector(span)"); // true
```
To solve this, this commit wraps the selector list passed to
`CSS.supports( "selector(:is(SELECTOR))" )` with `:is`, making it a single
selector again.
See:
* https://w3c.github.io/csswg-drafts/css-conditional-4/#at-supports-ext
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector-list
Fixes gh-5177
Closes gh-5178
Ref w3c/csswg-drafts#7280
2022-12-19 17:43:30 +00:00
assert . expect ( 10 ) ;
2014-02-26 23:13:26 +00:00
2020-03-16 20:49:29 +00:00
var fixture = jQuery ( "<div><h2><span></span></h2><div><p><span></span></p><p></p></div></div>" ) ;
2014-02-26 23:13:26 +00:00
2015-08-16 03:45:28 +00:00
assert . equal ( fixture . find ( "h2, div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
assert . equal ( fixture . find ( "h2, div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
assert . equal ( fixture . find ( "h2 , div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
assert . equal ( fixture . find ( "h2 , div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
Selector: Make selector lists work with `qSA` again
jQuery 3.6.2 started using `CSS.supports( "selector(SELECTOR)" )` before using
`querySelectorAll` on the selector. This was to solve gh-5098 - some selectors,
like `:has()`, now had their parameters parsed in a forgiving way, meaning
that `:has(:fakepseudo)` no longer throws but just returns 0 results, breaking
that jQuery mechanism.
A recent spec change made `CSS.supports( "selector(SELECTOR)" )` always use
non-forgiving parsing, allowing us to use this API for what we've used
`try-catch` before.
To solve the issue on the spec side for older jQuery versions, `:has()`
parameters are no longer using forgiving parsing in the latest spec update
but our new mechanism is more future-proof anyway.
However, the jQuery implementation has a bug - in
`CSS.supports( "selector(SELECTOR)" )`, `SELECTOR` needs to be
a `<complex-selector>` and not a `<complex-selector-list>`. Which means that
selector lists now skip `qSA` and go to the jQuery custom traversal:
```js
CSS.supports("selector(div:valid, span)"); // false
CSS.supports("selector(div:valid)"); // true
CSS.supports("selector(span)"); // true
```
To solve this, this commit wraps the selector list passed to
`CSS.supports( "selector(:is(SELECTOR))" )` with `:is`, making it a single
selector again.
See:
* https://w3c.github.io/csswg-drafts/css-conditional-4/#at-supports-ext
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector-list
Fixes gh-5177
Closes gh-5178
Ref w3c/csswg-drafts#7280
2022-12-19 17:43:30 +00:00
assert . equal ( fixture . find ( "h2 ,div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
assert . equal ( fixture . find ( "h2 ,div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
assert . equal ( fixture . find ( "h2,div p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
assert . equal ( fixture . find ( "h2,div p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
assert . equal ( fixture . find ( "h2\t,\rdiv p" ) . filter ( "p" ) . length , 2 , "has to find two <p>" ) ;
assert . equal ( fixture . find ( "h2\t,\rdiv p" ) . filter ( "h2" ) . length , 1 , "has to find one <h2>" ) ;
} ) ;
QUnit . test ( "comma-separated, only supported natively (gh-5177)" , function ( assert ) {
assert . expect ( 5 ) ;
var fixture = jQuery ( "<div><input/><span></span></div>" ) ;
fixture . appendTo ( "#qunit-fixture" ) ;
assert . equal ( fixture . find ( "input:valid, span" ) . length , 2 , "has to find two elements" ) ;
assert . equal ( fixture . find ( "input:valid , span" ) . length , 2 , "has to find two elements" ) ;
assert . equal ( fixture . find ( "input:valid ,span" ) . length , 2 , "has to find two elements" ) ;
assert . equal ( fixture . find ( "input:valid,span" ) . length , 2 , "has to find two elements" ) ;
assert . equal ( fixture . find ( "input:valid\t,\rspan" ) . length , 2 , "has to find two elements" ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2014-02-26 23:13:26 +00:00
2015-08-16 03:45:28 +00:00
QUnit . test ( "child and adjacent" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 43 ) ;
var siblingFirst , en , nothiddendiv ;
2014-02-26 23:32:02 +00:00
2016-05-10 09:12:28 +00:00
assert . t ( "Child" , "p > a" , [ "simon1" , "google" , "groups" , "mark" , "yahoo" , "simon" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Child minus leading whitespace" , "p> a" , [ "simon1" , "google" , "groups" , "mark" , "yahoo" , "simon" ] ) ;
assert . t ( "Child minus trailing whitespace" , "p >a" , [ "simon1" , "google" , "groups" , "mark" , "yahoo" , "simon" ] ) ;
assert . t ( "Child minus whitespace" , "p>a" , [ "simon1" , "google" , "groups" , "mark" , "yahoo" , "simon" ] ) ;
2016-05-10 09:12:28 +00:00
assert . t ( "Child w/ Class" , "p > a.blog" , [ "mark" , "simon" ] ) ;
assert . t ( "All Children" , "code > *" , [ "anchor1" , "anchor2" ] ) ;
assert . selectInFixture ( "All Grandchildren" , "p > * > *" , [ "anchor1" , "anchor2" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Rooted tag adjacent" , "#qunit-fixture a + a" , [ "groups" , "tName2ID" ] ) ;
assert . t ( "Rooted tag adjacent minus whitespace" , "#qunit-fixture a+a" , [ "groups" , "tName2ID" ] ) ;
assert . t ( "Rooted tag adjacent minus leading whitespace" , "#qunit-fixture a +a" ,
[ "groups" , "tName2ID" ] ) ;
assert . t ( "Rooted tag adjacent minus trailing whitespace" , "#qunit-fixture a+ a" ,
[ "groups" , "tName2ID" ] ) ;
assert . t ( "Tag adjacent" , "p + p" , [ "ap" , "en" , "sap" ] ) ;
assert . t ( "#id adjacent" , "#firstp + p" , [ "ap" ] ) ;
assert . t ( "Tag#id adjacent" , "p#firstp + p" , [ "ap" ] ) ;
assert . t ( "Tag[attr] adjacent" , "p[lang=en] + p" , [ "sap" ] ) ;
assert . t ( "Tag.class adjacent" , "a.GROUPS + code + a" , [ "mark" ] ) ;
assert . t ( "Comma, Child, and Adjacent" , "#qunit-fixture a + a, code > a" ,
[ "groups" , "anchor1" , "anchor2" , "tName2ID" ] ) ;
assert . t ( "Element Preceded By" , "#qunit-fixture p ~ div" ,
[ "foo" , "nothiddendiv" , "moretests" , "tabindex-tests" , "liveHandlerOrder" , "siblingTest" , "fx-test-group" ] ) ;
assert . t ( "Element Preceded By" , "#first ~ div" ,
[ "moretests" , "tabindex-tests" , "liveHandlerOrder" , "siblingTest" , "fx-test-group" ] ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Element Preceded By" , "#groups ~ a" , [ "mark" ] ) ;
assert . t ( "Element Preceded By" , "#length ~ input" , [ "idTest" ] ) ;
assert . t ( "Element Preceded By" , "#siblingfirst ~ em" , [ "siblingnext" , "siblingthird" ] ) ;
assert . t ( "Element Preceded By (multiple)" , "#siblingTest em ~ em ~ em ~ span" , [ "siblingspan" ] ) ;
2015-11-10 18:26:15 +00:00
2019-06-26 19:39:10 +00:00
siblingFirst = document . getElementById ( "siblingfirst" ) ;
2023-02-13 17:34:41 +00:00
assert . deepEqual ( jQuery ( "+ em" , siblingFirst ) . get ( ) , q ( "siblingnext" ) ,
"Element Directly Preceded By with a context." ) ;
assert . deepEqual ( jQuery ( "~ em" , siblingFirst ) . get ( ) , q ( "siblingnext" , "siblingthird" ) ,
"Element Preceded By with a context." ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "~ em:first" , siblingFirst ) . get ( ) , q ( "siblingnext" ) ,
2019-07-29 19:14:46 +00:00
"Element Preceded By positional with a context." ) ;
} else {
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
}
2023-02-13 17:34:41 +00:00
en = document . getElementById ( "en" ) ;
assert . deepEqual ( jQuery ( "+ p, a" , en ) . get ( ) , q ( "yahoo" , "sap" ) ,
"Compound selector with context, beginning with sibling test." ) ;
assert . deepEqual ( jQuery ( "a, + p" , en ) . get ( ) , q ( "yahoo" , "sap" ) ,
"Compound selector with context, containing sibling test." ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2015-11-10 18:26:15 +00:00
assert . t ( "Element Preceded By, Containing" , "#liveHandlerOrder ~ div em:contains('1')" , [ "siblingfirst" ] ) ;
assert . t ( "Combinators are not skipped when mixing general and specific" , "#siblingTest > em:contains('x') + em ~ span" , [ ] ) ;
2019-07-29 19:14:46 +00:00
} else {
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
}
if ( QUnit . jQuerySelectorsPos ) {
2022-01-04 15:27:18 +00:00
assert . equal ( jQuery ( "#listWithTabIndex li:eq(2) ~ li" ) . length , 1 , "Find by general sibling combinator (trac-8310)" ) ;
2019-06-26 19:39:10 +00:00
nothiddendiv = document . getElementById ( "nothiddendiv" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "> :first" , nothiddendiv ) . get ( ) , q ( "nothiddendivchild" ) ,
2019-06-26 19:39:10 +00:00
"Verify child context positional selector" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "> :eq(0)" , nothiddendiv ) . get ( ) , q ( "nothiddendivchild" ) ,
2019-06-26 19:39:10 +00:00
"Verify child context positional selector" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "> *:first" , nothiddendiv ) . get ( ) , q ( "nothiddendivchild" ) ,
2019-06-26 19:39:10 +00:00
"Verify child context positional selector" ) ;
2015-11-10 18:26:15 +00:00
} else {
2019-07-29 19:14:46 +00:00
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
2015-11-10 18:26:15 +00:00
}
2015-09-08 00:26:29 +00:00
assert . t ( "Multiple combinators selects all levels" , "#siblingTest em *" , [ "siblingchild" , "siblinggrandchild" , "siblinggreatgrandchild" ] ) ;
assert . t ( "Multiple combinators selects all levels" , "#siblingTest > em *" , [ "siblingchild" , "siblinggrandchild" , "siblinggreatgrandchild" ] ) ;
assert . t ( "Multiple sibling combinators doesn't miss general siblings" , "#siblingTest > em:first-child + em ~ span" , [ "siblingspan" ] ) ;
2014-02-26 23:32:02 +00:00
2022-01-04 15:27:18 +00:00
assert . equal ( jQuery ( "#listWithTabIndex" ) . length , 1 , "Parent div for next test is found via ID (trac-8310)" ) ;
assert . equal ( jQuery ( "#__sizzle__" ) . length , 0 , "Make sure the temporary id assigned by sizzle is cleared out (trac-8310)" ) ;
assert . equal ( jQuery ( "#listWithTabIndex" ) . length , 1 , "Parent div for previous test is still found via ID (trac-8310)" ) ;
2014-02-26 23:32:02 +00:00
2015-09-08 00:26:29 +00:00
assert . t ( "Verify deep class selector" , "div.blah > p > a" , [ ] ) ;
assert . t ( "No element deep selector" , "div.foo > span > a" , [ ] ) ;
assert . t ( "Non-existent ancestors" , ".fototab > .thumbnails > a" , [ ] ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2014-02-26 23:32:02 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - existence" , function ( assert ) {
assert . expect ( 7 ) ;
2014-02-26 23:13:26 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "On element" , "#qunit-fixture a[title]" , [ "google" ] ) ;
assert . t ( "On element (whitespace ignored)" , "#qunit-fixture a[ title ]" , [ "google" ] ) ;
assert . t ( "On element (case-insensitive)" , "#qunit-fixture a[TITLE]" , [ "google" ] ) ;
assert . t ( "On any element" , "#qunit-fixture *[title]" , [ "google" ] ) ;
assert . t ( "On implicit element" , "#qunit-fixture [title]" , [ "google" ] ) ;
assert . t ( "Boolean" , "#select2 option[selected]" , [ "option2d" ] ) ;
assert . t ( "For attribute on label" , "form label[for]" , [ "label-for" ] ) ;
} ) ;
2012-05-30 17:46:50 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - equals" , function ( assert ) {
assert . expect ( 20 ) ;
2012-12-08 21:28:10 +00:00
2019-06-26 19:39:10 +00:00
var withScript ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "Identifier" , "#qunit-fixture a[rel=bookmark]" , [ "simon1" ] ) ;
assert . t ( "Identifier with underscore" , "input[id=types_all]" , [ "types_all" ] ) ;
assert . t ( "String" , "#qunit-fixture a[rel='bookmark']" , [ "simon1" ] ) ;
assert . t ( "String (whitespace ignored)" , "#qunit-fixture a[ rel = 'bookmark' ]" , [ "simon1" ] ) ;
2019-10-21 17:03:48 +00:00
assert . t ( "Non-identifier string" , "#qunit-fixture a[href='https://www.google.com/']" , [ "google" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Empty string" , "#select1 option[value='']" , [ "option1a" ] ) ;
2014-02-26 23:23:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Number" ,
"#qunit-fixture option[value=1]" ,
[ "option1b" , "option2b" , "option3b" , "option4b" , "option5c" ] ) ;
assert . t ( "negative number" ,
"#qunit-fixture li[tabIndex=-1]" , [ "foodWithNegativeTabIndex" ] ) ;
} else {
2019-07-29 19:14:46 +00:00
assert . ok ( "skip" , "Number value not supported in selector-native" ) ;
assert . ok ( "skip" , "Negative number value not supported in selector-native" ) ;
2019-06-26 19:39:10 +00:00
}
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "Non-ASCII identifier" , "span[lang=中文]" , [ "台北" ] ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "input[type=text]" , "#form input[type=text]" , [ "text1" , "text2" , "hidden2" , "name" ] ) ;
assert . t ( "input[type=search]" , "#form input[type=search]" , [ "search" ] ) ;
2020-03-16 20:49:29 +00:00
withScript = supportjQuery ( "<div><span><script src=''></script></span></div>" ) ;
2022-01-04 15:27:18 +00:00
assert . ok ( withScript . find ( "#moretests script[src]" ) . has ( "script" ) , "script[src] (jQuery trac-13777)" ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Boolean attribute equals name" , "#select2 option[selected='selected']" , [ "option2d" ] ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "for Attribute in form" , "#form [for=action]" , [ "label-for" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Grouped Form Elements - name" , "input[name='foo[bar]']" , [ "hidden2" ] ) ;
assert . t ( "Value" , "input[value=Test]" , [ "text1" , "text2" ] ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "input[data-comma='0,1']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "el12087" ) ,
"Without context, single-quoted attribute containing ','" ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "input[data-comma=\"0,1\"]" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "el12087" ) ,
"Without context, double-quoted attribute containing ','" ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "input[data-comma='0,1']" , document . getElementById ( "t12087" ) ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "el12087" ) ,
"With context, single-quoted attribute containing ','" ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "input[data-comma=\"0,1\"]" , document . getElementById ( "t12087" ) ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "el12087" ) ,
"With context, double-quoted attribute containing ','" ) ;
} ) ;
2019-07-29 19:14:46 +00:00
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "attributes - does not equal" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 2 ) ;
assert . t ( "string" , "#ap a[hreflang!='en']" , [ "google" , "groups" , "anchor1" ] ) ;
assert . t ( "Empty values" , "#select1 option[value!='']" , [ "option1b" , "option1c" , "option1d" ] ) ;
} ) ;
QUnit . test ( "attributes - starts with" , function ( assert ) {
assert . expect ( 4 ) ;
2019-10-21 17:03:48 +00:00
assert . t ( "string (whitespace ignored)" , "a[href ^= 'https://www']" , [ "google" , "yahoo" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "href starts with hash" , "p a[href^='#']" , [ "anchor2" ] ) ;
assert . t ( "string containing '['" , "input[name^='foo[']" , [ "hidden2" ] ) ;
assert . t ( "string containing '[' ... ']'" , "input[name^='foo[bar]']" , [ "hidden2" ] ) ;
} ) ;
QUnit . test ( "attributes - contains" , function ( assert ) {
assert . expect ( 4 ) ;
assert . t ( "string (whitespace ignored)" , "a[href *= 'google']" , [ "google" , "groups" ] ) ;
assert . t ( "string like '[' ... ']']" , "input[name*='[bar]']" , [ "hidden2" ] ) ;
assert . t ( "string containing '['...']" , "input[name*='foo[bar]']" , [ "hidden2" ] ) ;
assert . t ( "href contains hash" , "p a[href*='#']" , [ "simon1" , "anchor2" ] ) ;
} ) ;
QUnit . test ( "attributes - ends with" , function ( assert ) {
assert . expect ( 4 ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "string (whitespace ignored)" , "a[href $= 'org/']" , [ "mark" ] ) ;
assert . t ( "string ending with ']'" , "input[name$='bar]']" , [ "hidden2" ] ) ;
assert . t ( "string like '[' ... ']'" , "input[name$='[bar]']" , [ "hidden2" ] ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Attribute containing []" , "input[name$='foo[bar]']" , [ "hidden2" ] ) ;
2019-06-26 19:39:10 +00:00
} ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - whitespace list includes" , function ( assert ) {
assert . expect ( 3 ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "string found at the beginning" ,
"input[data-15233~='foo']" ,
[ "t15233-single" , "t15233-double" , "t15233-double-tab" , "t15233-double-nl" , "t15233-triple" ] ) ;
assert . t ( "string found in the middle" ,
"input[data-15233~='bar']" ,
[ "t15233-double" , "t15233-double-tab" , "t15233-double-nl" , "t15233-triple" ] ) ;
assert . t ( "string found at the end" , "input[data-15233~='baz']" , [ "t15233-triple" ] ) ;
} ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - hyphen-prefix matches" , function ( assert ) {
assert . expect ( 3 ) ;
2015-11-10 18:26:15 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "string" , "#names-group span[id|='name']" , [ "name-is-example" , "name-is-div" ] ) ;
assert . t ( "string containing hyphen" ,
"#names-group span[id|='name-is']" ,
[ "name-is-example" , "name-is-div" ] ) ;
assert . t ( "string ending with hyphen" , "#names-group span[id|='name-is-']" , [ ] ) ;
} ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - special characters" , function ( assert ) {
2019-08-20 18:05:37 +00:00
assert . expect ( 16 ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
var attrbad ;
var div = document . createElement ( "div" ) ;
2014-02-26 23:23:10 +00:00
2022-01-12 22:23:42 +00:00
// trac-3729
2019-06-26 19:39:10 +00:00
div . innerHTML = "<div id='foo' xml:test='something'></div>" ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "[xml\\:test]" , div ) . get ( ) ,
2019-06-26 19:39:10 +00:00
[ div . firstChild ] ,
"attribute name containing colon" ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
// Make sure attribute value quoting works correctly.
// See jQuery trac-6093; trac-6428; trac-13894.
// Use seeded results to bypass querySelectorAll optimizations.
2014-02-26 23:23:10 +00:00
attrbad = jQuery (
"<input type='hidden' id='attrbad_space' name='foo bar'/>" +
"<input type='hidden' id='attrbad_dot' value='2' name='foo.baz'/>" +
"<input type='hidden' id='attrbad_brackets' value='2' name='foo[baz]'/>" +
2019-08-20 18:05:37 +00:00
"<input type='hidden' id='attrbad_leading_digits' name='agent' value='007'/>" +
2014-02-26 23:23:10 +00:00
"<input type='hidden' id='attrbad_injection' data-attr='foo_baz']'/>" +
"<input type='hidden' id='attrbad_quote' data-attr='''/>" +
"<input type='hidden' id='attrbad_backslash' data-attr='\'/>" +
"<input type='hidden' id='attrbad_backslash_quote' data-attr='\''/>" +
"<input type='hidden' id='attrbad_backslash_backslash' data-attr='\\'/>" +
"<input type='hidden' id='attrbad_unicode' data-attr='一'/>"
2015-08-16 06:59:58 +00:00
) . appendTo ( "#qunit-fixture" ) . get ( ) ;
2014-02-26 23:23:10 +00:00
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[name=foo\\ bar]" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_space" ) ,
"identifier containing space" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[name=foo\\.baz]" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_dot" ) ,
"identifier containing dot" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[name=foo\\[baz\\]]" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_brackets" ) ,
"identifier containing brackets" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='foo_baz\\']']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_injection" ) ,
"string containing quote and right bracket" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[value=\\30 \\30\\37 ]" ) . get ( ) ,
2019-08-20 18:05:37 +00:00
q ( "attrbad_leading_digits" ) ,
"identifier containing escaped leading digits with whitespace termination" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[value=\\00003007]" ) . get ( ) ,
2019-08-20 18:05:37 +00:00
q ( "attrbad_leading_digits" ) ,
"identifier containing escaped leading digits without whitespace termination" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\'']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_quote" ) ,
"string containing quote" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\\\']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash" ) ,
"string containing backslash" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\\\\\'']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash_quote" ) ,
"string containing backslash and quote" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\\\\\\\']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash_backslash" ) ,
"string containing adjacent backslashes" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\5C\\\\']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash_backslash" ) ,
"string containing numeric-escape backslash and backslash" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\5C \\\\']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash_backslash" ) ,
"string containing numeric-escape-with-trailing-space backslash and backslash" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\5C\t\\\\']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_backslash_backslash" ) ,
"string containing numeric-escape-with-trailing-tab backslash and backslash" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\04e00']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_unicode" ) ,
"Long numeric escape (BMP)" ) ;
document . getElementById ( "attrbad_unicode" ) . setAttribute ( "data-attr" , "\uD834\uDF06A" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( attrbad ) . filter ( "input[data-attr='\\01D306A']" ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "attrbad_unicode" ) ,
"Long numeric escape (non-BMP)" ) ;
} ) ;
2014-02-26 23:23:10 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "attributes - others" , function ( assert ) {
2019-11-18 21:10:55 +00:00
assert . expect ( 14 ) ;
2019-06-26 19:39:10 +00:00
var div = document . getElementById ( "foo" ) ;
assert . t ( "Find elements with a tabindex attribute" , "[tabindex]" , [ "listWithTabIndex" , "foodWithNegativeTabIndex" , "linkWithTabIndex" , "linkWithNegativeTabIndex" , "linkWithNoHrefWithTabIndex" , "linkWithNoHrefWithNegativeTabIndex" ] ) ;
assert . t ( "Selector list with multiple quoted attribute-equals" ,
"#form input[type='radio'], #form input[type='hidden']" ,
[ "radio1" , "radio2" , "hidden1" ] ) ;
assert . t ( "Selector list with differently-quoted attribute-equals" ,
"#form input[type='radio'], #form input[type=\"hidden\"]" ,
[ "radio1" , "radio2" , "hidden1" ] ) ;
assert . t ( "Selector list with quoted and unquoted attribute-equals" ,
"#form input[type='radio'], #form input[type=hidden]" ,
[ "radio1" , "radio2" , "hidden1" ] ) ;
2014-02-26 23:23:10 +00:00
2015-09-08 00:26:29 +00:00
assert . t ( "Object.prototype property \"constructor\" (negative)" , "[constructor]" , [ ] ) ;
assert . t ( "Gecko Object.prototype property \"watch\" (negative)" , "[watch]" , [ ] ) ;
2014-02-26 23:23:10 +00:00
div . setAttribute ( "constructor" , "foo" ) ;
div . setAttribute ( "watch" , "bar" ) ;
2015-09-08 00:26:29 +00:00
assert . t ( "Object.prototype property \"constructor\"" , "[constructor='foo']" , [ "foo" ] ) ;
assert . t ( "Gecko Object.prototype property \"watch\"" , "[watch='bar']" , [ "foo" ] ) ;
2014-02-26 23:23:10 +00:00
2022-01-04 15:27:18 +00:00
// trac-11115
2019-06-26 19:39:10 +00:00
assert . ok ( jQuery ( "<input type='checkbox' checked='checked'/>" ) . prop ( "checked" , false ) . is ( "[checked]" ) ,
"[checked] selects by attribute (positive)"
) ;
assert . ok ( ! jQuery ( "<input type='checkbox'/>" ) . prop ( "checked" , true ) . is ( "[checked]" ) ,
"[checked] selects by attribute (negative)"
) ;
2019-11-18 21:10:55 +00:00
assert . t ( "empty name" , "[name='']" , [ "name-empty" ] ) ;
assert . t ( "prefixed empty name" , "#empty-name-parent [name='']" , [ "name-empty" ] ) ;
var emptyNameContainer = jQuery ( ".empty-name-container" ) ;
assert . deepEqual ( emptyNameContainer . find ( "[name='']" ) . get ( ) ,
q ( "name-empty" ) ,
"empty name with context" ) ;
assert . deepEqual ( emptyNameContainer . find ( "#empty-name-parent [name='']" ) . get ( ) ,
q ( "name-empty" ) ,
"prefixed empty name with context" ) ;
2019-06-26 19:39:10 +00:00
} ) ;
QUnit . test ( "pseudo - (parent|empty)" , function ( assert ) {
assert . expect ( 3 ) ;
assert . t ( "Empty" , "#qunit-fixture ul:empty" , [ "firstUL" ] ) ;
assert . t ( "Empty with comment node" , "#qunit-fixture ol:empty" , [ "empty" ] ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Is A Parent" , "#qunit-fixture p:parent" ,
[ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
} else {
assert . ok ( "skip" , ":parent not supported in selector-native" ) ;
}
} ) ;
QUnit . test ( "pseudo - (first|last|only)-(child|of-type)" , function ( assert ) {
assert . expect ( 12 ) ;
assert . t ( "First Child" , "#qunit-fixture p:first-child" , [ "firstp" , "sndp" ] ) ;
assert . t ( "First Child (leading id)" , "#qunit-fixture p:first-child" , [ "firstp" , "sndp" ] ) ;
assert . t ( "First Child (leading class)" , ".nothiddendiv div:first-child" , [ "nothiddendivchild" ] ) ;
assert . t ( "First Child (case-insensitive)" , "#qunit-fixture p:FIRST-CHILD" , [ "firstp" , "sndp" ] ) ;
assert . t ( "Last Child" , "#qunit-fixture p:last-child" , [ "sap" ] ) ;
assert . t ( "Last Child (leading id)" , "#qunit-fixture a:last-child" , [ "simon1" , "anchor1" , "mark" , "yahoo" , "anchor2" , "simon" , "liveLink1" , "liveLink2" ] ) ;
assert . t ( "Only Child" , "#qunit-fixture a:only-child" , [ "simon1" , "anchor1" , "yahoo" , "anchor2" , "liveLink1" , "liveLink2" ] ) ;
assert . t ( "First-of-type" , "#qunit-fixture > p:first-of-type" , [ "firstp" ] ) ;
assert . t ( "Last-of-type" , "#qunit-fixture > p:last-of-type" , [ "first" ] ) ;
assert . t ( "Only-of-type" , "#qunit-fixture > :only-of-type" , [ "name+value" , "firstUL" , "empty" , "floatTest" , "iframe" , "table" , "last" ] ) ;
// Verify that the child position isn't being cached improperly
var secondChildren = jQuery ( "p:nth-child(2)" ) . before ( "<div></div>" ) ;
assert . t ( "No longer second child" , "p:nth-child(2)" , [ ] ) ;
secondChildren . prev ( ) . remove ( ) ;
assert . t ( "Restored second child" , "p:nth-child(2)" , [ "ap" , "en" ] ) ;
} ) ;
QUnit . test ( "pseudo - nth-child" , function ( assert ) {
assert . expect ( 30 ) ;
assert . t ( "Nth-child" , "p:nth-child(1)" , [ "firstp" , "sndp" ] ) ;
assert . t ( "Nth-child (with whitespace)" , "p:nth-child( 1 )" , [ "firstp" , "sndp" ] ) ;
assert . t ( "Nth-child (case-insensitive)" , "#form #select1 option:NTH-child(3)" , [ "option1c" ] ) ;
assert . t ( "Not nth-child" , "#qunit-fixture p:not(:nth-child(1))" , [ "ap" , "en" , "sap" , "first" ] ) ;
assert . t ( "Nth-child(2)" , "#qunit-fixture form#form > *:nth-child(2)" , [ "text1" ] ) ;
assert . t ( "Nth-child(2)" , "#qunit-fixture form#form > :nth-child(2)" , [ "text1" ] ) ;
assert . t ( "Nth-child(-1)" , "#form #select1 option:nth-child(-1)" , [ ] ) ;
assert . t ( "Nth-child(3)" , "#form #select1 option:nth-child(3)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(0n+3)" , "#form #select1 option:nth-child(0n+3)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(1n+0)" , "#form #select1 option:nth-child(1n+0)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-child(1n)" , "#form #select1 option:nth-child(1n)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-child(n)" , "#form #select1 option:nth-child(n)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-child(even)" , "#form #select1 option:nth-child(even)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-child(odd)" , "#form #select1 option:nth-child(odd)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-child(2n)" , "#form #select1 option:nth-child(2n)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-child(2n+1)" , "#form #select1 option:nth-child(2n+1)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-child(2n + 1)" , "#form #select1 option:nth-child(2n + 1)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-child(+2n + 1)" , "#form #select1 option:nth-child(+2n + 1)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-child(3n)" , "#form #select1 option:nth-child(3n)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(3n+1)" , "#form #select1 option:nth-child(3n+1)" , [ "option1a" , "option1d" ] ) ;
assert . t ( "Nth-child(3n+2)" , "#form #select1 option:nth-child(3n+2)" , [ "option1b" ] ) ;
assert . t ( "Nth-child(3n+3)" , "#form #select1 option:nth-child(3n+3)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(3n-1)" , "#form #select1 option:nth-child(3n-1)" , [ "option1b" ] ) ;
assert . t ( "Nth-child(3n-2)" , "#form #select1 option:nth-child(3n-2)" , [ "option1a" , "option1d" ] ) ;
assert . t ( "Nth-child(3n-3)" , "#form #select1 option:nth-child(3n-3)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(3n+0)" , "#form #select1 option:nth-child(3n+0)" , [ "option1c" ] ) ;
assert . t ( "Nth-child(-1n+3)" , "#form #select1 option:nth-child(-1n+3)" , [ "option1a" , "option1b" , "option1c" ] ) ;
assert . t ( "Nth-child(-n+3)" , "#form #select1 option:nth-child(-n+3)" , [ "option1a" , "option1b" , "option1c" ] ) ;
assert . t ( "Nth-child(-1n + 3)" , "#form #select1 option:nth-child(-1n + 3)" , [ "option1a" , "option1b" , "option1c" ] ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors || this . safari ) {
2019-06-26 19:39:10 +00:00
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( [ document . createElement ( "a" ) ] . concat ( q ( "ap" ) ) )
. filter ( ":nth-child(n)" )
. get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "ap" ) ,
"Seeded nth-child"
) ;
} else {
// Support: Chrome 75+, Firefox 67+
// Some browsers mark disconnected elements as matching `:nth-child(n)`
// so let's skip the test.
assert . ok ( "skip" , "disconnected elements match ':nth-child(n)' in Chrome/Firefox" ) ;
}
} ) ;
QUnit . test ( "pseudo - nth-last-child" , function ( assert ) {
assert . expect ( 30 ) ;
2020-03-16 20:49:29 +00:00
jQuery ( "#qunit-fixture" ) . append ( "<form id='nth-last-child-form'></form><i></i><i></i><i></i><i></i>" ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Nth-last-child" , "form:nth-last-child(5)" , [ "nth-last-child-form" ] ) ;
assert . t ( "Nth-last-child (with whitespace)" , "form:nth-last-child( 5 )" , [ "nth-last-child-form" ] ) ;
assert . t ( "Nth-last-child (case-insensitive)" , "#form #select1 option:NTH-last-child(3)" , [ "option1b" ] ) ;
assert . t ( "Not nth-last-child" , "#qunit-fixture p:not(:nth-last-child(1))" , [ "firstp" , "ap" , "sndp" , "en" , "first" ] ) ;
assert . t ( "Nth-last-child(-1)" , "#form #select1 option:nth-last-child(-1)" , [ ] ) ;
assert . t ( "Nth-last-child(3)" , "#form #select1 :nth-last-child(3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(3)" , "#form #select1 *:nth-last-child(3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(3)" , "#form #select1 option:nth-last-child(3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(0n+3)" , "#form #select1 option:nth-last-child(0n+3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(1n+0)" , "#form #select1 option:nth-last-child(1n+0)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-last-child(1n)" , "#form #select1 option:nth-last-child(1n)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-last-child(n)" , "#form #select1 option:nth-last-child(n)" , [ "option1a" , "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-last-child(even)" , "#form #select1 option:nth-last-child(even)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-last-child(odd)" , "#form #select1 option:nth-last-child(odd)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-last-child(2n)" , "#form #select1 option:nth-last-child(2n)" , [ "option1a" , "option1c" ] ) ;
assert . t ( "Nth-last-child(2n+1)" , "#form #select1 option:nth-last-child(2n+1)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-last-child(2n + 1)" , "#form #select1 option:nth-last-child(2n + 1)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-last-child(+2n + 1)" , "#form #select1 option:nth-last-child(+2n + 1)" , [ "option1b" , "option1d" ] ) ;
assert . t ( "Nth-last-child(3n)" , "#form #select1 option:nth-last-child(3n)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(3n+1)" , "#form #select1 option:nth-last-child(3n+1)" , [ "option1a" , "option1d" ] ) ;
assert . t ( "Nth-last-child(3n+2)" , "#form #select1 option:nth-last-child(3n+2)" , [ "option1c" ] ) ;
assert . t ( "Nth-last-child(3n+3)" , "#form #select1 option:nth-last-child(3n+3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(3n-1)" , "#form #select1 option:nth-last-child(3n-1)" , [ "option1c" ] ) ;
assert . t ( "Nth-last-child(3n-2)" , "#form #select1 option:nth-last-child(3n-2)" , [ "option1a" , "option1d" ] ) ;
assert . t ( "Nth-last-child(3n-3)" , "#form #select1 option:nth-last-child(3n-3)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(3n+0)" , "#form #select1 option:nth-last-child(3n+0)" , [ "option1b" ] ) ;
assert . t ( "Nth-last-child(-1n+3)" , "#form #select1 option:nth-last-child(-1n+3)" , [ "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-last-child(-n+3)" , "#form #select1 option:nth-last-child(-n+3)" , [ "option1b" , "option1c" , "option1d" ] ) ;
assert . t ( "Nth-last-child(-1n + 3)" , "#form #select1 option:nth-last-child(-1n + 3)" , [ "option1b" , "option1c" , "option1d" ] ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors || this . safari ) {
2019-06-26 19:39:10 +00:00
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( [ document . createElement ( "a" ) ] . concat ( q ( "ap" ) ) )
. filter ( ":nth-last-child(n)" )
. get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "ap" ) ,
"Seeded nth-last-child"
) ;
} else {
// Support: Chrome 75+, Firefox 67+
// Some browsers mark disconnected elements as matching `:nth-last-child(n)`
// so let's skip the test.
assert . ok ( "skip" , "disconnected elements match ':nth-last-child(n)' in Chrome/Firefox" ) ;
}
} ) ;
QUnit . test ( "pseudo - nth-of-type" , function ( assert ) {
assert . expect ( 9 ) ;
assert . t ( "Nth-of-type(-1)" , ":nth-of-type(-1)" , [ ] ) ;
assert . t ( "Nth-of-type(3)" , "#ap :nth-of-type(3)" , [ "mark" ] ) ;
assert . t ( "Nth-of-type(n)" , "#ap :nth-of-type(n)" , [ "google" , "groups" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-of-type(0n+3)" , "#ap :nth-of-type(0n+3)" , [ "mark" ] ) ;
assert . t ( "Nth-of-type(2n)" , "#ap :nth-of-type(2n)" , [ "groups" ] ) ;
assert . t ( "Nth-of-type(even)" , "#ap :nth-of-type(even)" , [ "groups" ] ) ;
assert . t ( "Nth-of-type(2n+1)" , "#ap :nth-of-type(2n+1)" , [ "google" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-of-type(odd)" , "#ap :nth-of-type(odd)" , [ "google" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-of-type(-n+2)" , "#qunit-fixture > :nth-of-type(-n+2)" , [ "firstp" , "ap" , "foo" , "nothiddendiv" , "name+value" , "firstUL" , "empty" , "form" , "floatTest" , "iframe" , "lengthtest" , "table" , "last" ] ) ;
} ) ;
QUnit . test ( "pseudo - nth-last-of-type" , function ( assert ) {
assert . expect ( 9 ) ;
assert . t ( "Nth-last-of-type(-1)" , ":nth-last-of-type(-1)" , [ ] ) ;
assert . t ( "Nth-last-of-type(3)" , "#ap :nth-last-of-type(3)" , [ "google" ] ) ;
assert . t ( "Nth-last-of-type(n)" , "#ap :nth-last-of-type(n)" , [ "google" , "groups" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-last-of-type(0n+3)" , "#ap :nth-last-of-type(0n+3)" , [ "google" ] ) ;
assert . t ( "Nth-last-of-type(2n)" , "#ap :nth-last-of-type(2n)" , [ "groups" ] ) ;
assert . t ( "Nth-last-of-type(even)" , "#ap :nth-last-of-type(even)" , [ "groups" ] ) ;
assert . t ( "Nth-last-of-type(2n+1)" , "#ap :nth-last-of-type(2n+1)" , [ "google" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-last-of-type(odd)" , "#ap :nth-last-of-type(odd)" , [ "google" , "code1" , "anchor1" , "mark" ] ) ;
assert . t ( "Nth-last-of-type(-n+2)" , "#qunit-fixture > :nth-last-of-type(-n+2)" , [ "ap" , "name+value" , "first" , "firstUL" , "empty" , "floatTest" , "iframe" , "table" , "testForm" , "disabled-tests" , "siblingTest" , "fx-test-group" , "last" ] ) ;
} ) ;
2019-07-29 19:14:46 +00:00
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "pseudo - has" , function ( assert ) {
2022-09-19 18:56:02 +00:00
assert . expect ( 4 ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Basic test" , "p:has(a)" , [ "firstp" , "ap" , "en" , "sap" ] ) ;
assert . t ( "Basic test (irrelevant whitespace)" , "p:has( a )" , [ "firstp" , "ap" , "en" , "sap" ] ) ;
assert . t ( "Nested with overlapping candidates" ,
"#qunit-fixture div:has(div:has(div:not([id])))" ,
[ "moretests" , "t2037" , "fx-test-group" , "fx-queue" ] ) ;
2022-09-19 18:56:02 +00:00
// Support: Safari 15.4+, Chrome 105+
// `qSA` in Safari/Chrome throws for `:has()` with only unsupported arguments
// but if you add a supported arg to the list, it will run and just potentially
// return no results. Make sure this is accounted for. (gh-5098)
// Note: Chrome 105 has this behavior only in 105.0.5195.125 or newer;
// initially it shipped with a fully forgiving parsing in `:has()`.
assert . t ( "Nested with list arguments" ,
"#qunit-fixture div:has(faketag, div:has(faketag, div:not([id])))" ,
[ "moretests" , "t2037" , "fx-test-group" , "fx-queue" ] ) ;
2019-06-26 19:39:10 +00:00
} ) ;
2019-07-29 19:14:46 +00:00
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "pseudo - contains" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 9 ) ;
var gh335 = document . getElementById ( "qunit-fixture" ) . appendChild (
document . createElement ( "mark" ) ) ;
gh335 . id = "gh-335" ;
gh335 . appendChild ( document . createTextNode ( "raw line 1\nline 2" ) ) ;
2019-10-21 17:02:22 +00:00
assert . ok ( jQuery ( "a:contains('')" ) . length , "empty string" ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "unquoted argument" , "a:contains(Google)" , [ "google" , "groups" ] ) ;
assert . t ( "unquoted argument with whitespace" , "a:contains(Google Groups)" , [ "groups" ] ) ;
assert . t ( "quoted argument with whitespace and parentheses" ,
"a:contains('Google Groups (Link)')" , [ "groups" ] ) ;
assert . t ( "quoted argument with double quotes and parentheses" ,
"a:contains(\"(Link)\")" , [ "groups" ] ) ;
assert . t ( "unquoted argument with whitespace and paired parentheses" ,
"a:contains(Google Groups (Link))" , [ "groups" ] ) ;
assert . t ( "unquoted argument with paired parentheses" , "a:contains((Link))" , [ "groups" ] ) ;
assert . t ( "quoted argument with CSS escapes" ,
"span:contains(\"\\\"'\\53F0 \\5317 Ta\\301 ibe\\30C i\")" ,
[ "utf8class1" ] ) ;
assert . t ( "collapsed whitespace" , "mark:contains('line 1\\A line')" , [ "gh-335" ] ) ;
} ) ;
QUnit . test ( "pseudo - misc" , function ( assert ) {
assert . expect ( 32 ) ;
var select , tmp , input ;
2020-03-16 20:49:29 +00:00
jQuery ( "<h1 id='h1'></h1><h2 id='h2'></h2><h2 id='h2-2'></h2>" ) . prependTo ( "#qunit-fixture" ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Headers" , "#qunit-fixture :header" , [ "h1" , "h2" , "h2-2" ] ) ;
assert . t ( "Headers(case-insensitive)" , "#qunit-fixture :Header" , [ "h1" , "h2" , "h2-2" ] ) ;
} else {
assert . ok ( "skip" , ":header not supported in selector-native" ) ;
assert . ok ( "skip" , ":header not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Multiple matches with the same context (cache check)" ,
"#form select:has(option:first-child:contains('o'))" ,
[ "select1" , "select2" , "select3" , "select4" ]
) ;
2019-10-21 17:02:22 +00:00
assert . ok ( jQuery ( "#qunit-fixture :not(:has(:has(*)))" ) . length , "All not grandparents" ) ;
2019-06-26 19:39:10 +00:00
select = document . getElementById ( "select1" ) ;
assert . ok ( jQuery ( select ) . is ( ":has(option)" ) , "Has Option Matches" ) ;
} else {
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
}
tmp = document . createElement ( "div" ) ;
tmp . id = "tmp_input" ;
document . body . appendChild ( tmp ) ;
jQuery . each ( [ "button" , "submit" , "reset" ] , function ( i , type ) {
var els = jQuery (
"<input id='input_%' type='%'/><button id='button_%' type='%'>test</button>"
. replace ( /%/g , type )
) . appendTo ( tmp ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Input Buttons :" + type , "#tmp_input :" + type , [ "input_" + type , "button_" + type ] ) ;
assert . ok ( jQuery ( els [ 0 ] ) . is ( ":" + type ) , "Input Matches :" + type ) ;
assert . ok ( jQuery ( els [ 1 ] ) . is ( ":" + type ) , "Button Matches :" + type ) ;
} else {
assert . ok ( "skip" , ":" + type + " not supported in selector-native" ) ;
assert . ok ( "skip" , ":" + type + " not supported in selector-native" ) ;
assert . ok ( "skip" , ":" + type + " not supported in selector-native" ) ;
}
} ) ;
document . body . removeChild ( tmp ) ;
// Recreate tmp
tmp = document . createElement ( "div" ) ;
tmp . id = "tmp_input" ;
tmp . innerHTML = "<span>Hello I am focusable.</span>" ;
// Setting tabIndex should make the element focusable
2019-10-21 17:03:48 +00:00
// https://html.spec.whatwg.org/#the-tabindex-attribute
2019-06-26 19:39:10 +00:00
document . body . appendChild ( tmp ) ;
tmp . tabIndex = 0 ;
tmp . focus ( ) ;
if ( document . activeElement !== tmp || ( document . hasFocus && ! document . hasFocus ( ) ) ||
( document . querySelectorAll && ! document . querySelectorAll ( "div:focus" ) . length ) ) {
assert . ok ( true , "The div was not focused. Skip checking the :focus match." ) ;
assert . ok ( true , "The div was not focused. Skip checking the :focus match." ) ;
} else {
assert . t ( "tabIndex element focused" , ":focus" , [ "tmp_input" ] ) ;
assert . ok ( jQuery ( tmp ) . is ( ":focus" ) , ":focus matches tabIndex div" ) ;
}
// Blur tmp
tmp . blur ( ) ;
document . body . focus ( ) ;
assert . ok ( ! jQuery ( tmp ) . is ( ":focus" ) , ":focus doesn't match tabIndex div" ) ;
document . body . removeChild ( tmp ) ;
// Input focus/active
input = document . createElement ( "input" ) ;
input . type = "text" ;
input . id = "focus-input" ;
document . body . appendChild ( input ) ;
input . focus ( ) ;
// Inputs can't be focused unless the document has focus
if ( document . activeElement !== input || ( document . hasFocus && ! document . hasFocus ( ) ) ||
( document . querySelectorAll && ! document . querySelectorAll ( "input:focus" ) . length ) ) {
assert . ok ( true , "The input was not focused. Skip checking the :focus match." ) ;
assert . ok ( true , "The input was not focused. Skip checking the :focus match." ) ;
} else {
assert . t ( "Element focused" , "input:focus" , [ "focus-input" ] ) ;
assert . ok ( jQuery ( input ) . is ( ":focus" ) , ":focus matches" ) ;
}
input . blur ( ) ;
// When IE is out of focus, blur does not work. Force it here.
if ( document . activeElement === input ) {
document . body . focus ( ) ;
}
assert . ok ( ! jQuery ( input ) . is ( ":focus" ) , ":focus doesn't match" ) ;
document . body . removeChild ( input ) ;
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "[id='select1'] *:not(:last-child), [id='select2'] *:not(:last-child)" , q ( "qunit-fixture" ) [ 0 ] ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "option1a" , "option1b" , "option1c" , "option2a" , "option2b" , "option2c" ) ,
"caching system tolerates recursive selection"
) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
// Tokenization edge cases
assert . t ( "Sequential pseudos" , "#qunit-fixture p:has(:contains(mark)):has(code)" , [ "ap" ] ) ;
assert . t ( "Sequential pseudos" , "#qunit-fixture p:has(:contains(mark)):has(code):contains(This link)" , [ "ap" ] ) ;
assert . t ( "Pseudo argument containing ')'" , "p:has(>a.GROUPS[src!=')'])" , [ "ap" ] ) ;
assert . t ( "Pseudo argument containing ')'" , "p:has(>a.GROUPS[src!=')'])" , [ "ap" ] ) ;
assert . t ( "Pseudo followed by token containing ')'" , "p:contains(id=\"foo\")[id!=\\)]" , [ "sndp" ] ) ;
assert . t ( "Pseudo followed by token containing ')'" , "p:contains(id=\"foo\")[id!=')']" , [ "sndp" ] ) ;
assert . t ( "Multi-pseudo" , "#ap:has(*), #ap:has(*)" , [ "ap" ] ) ;
assert . t ( "Multi-pseudo with leading nonexistent id" , "#nonexistent:has(*), #ap:has(*)" , [ "ap" ] ) ;
2019-12-16 18:33:49 +00:00
assert . t ( "Tokenization stressor" , "a[class*=blog]:not(:has(*, :contains(!)), :contains(!)), br:contains(]), p:contains(]):not(.qunit-source), :not(:empty):not(:parent):not(.qunit-source)" , [ "ap" , "mark" , "yahoo" , "simon" ] ) ;
2019-06-26 19:39:10 +00:00
} else {
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":has supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
assert . t ( "Multi-positional" , "#ap:gt(0), #ap:lt(1)" , [ "ap" ] ) ;
assert . t ( "Multi-positional with leading nonexistent id" , "#nonexistent:gt(0), #ap:lt(1)" , [ "ap" ] ) ;
} else {
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
}
2019-06-26 19:39:10 +00:00
} ) ;
QUnit . test ( "pseudo - :not" , function ( assert ) {
assert . expect ( 43 ) ;
assert . t ( "Not" , "a.blog:not(.link)" , [ "mark" ] ) ;
2014-02-26 23:23:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Not - multiple" , "#form option:not(:contains(Nothing),#option1b,:selected)" , [ "option1c" , "option1d" , "option2b" , "option2c" , "option3d" , "option3e" , "option4e" , "option5b" , "option5c" ] ) ;
assert . t ( "Not - recursive" , "#form option:not(:not(:selected))[id^='option3']" , [ "option3b" , "option3c" ] ) ;
} else {
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
assert . t ( ":not() with :first" , "#foo p:not(:first) .link" , [ "simon" ] ) ;
} else {
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
}
2019-06-26 19:39:10 +00:00
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(.foo)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(#blargh)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
2021-04-13 20:11:45 +00:00
if ( QUnit . jQuerySelectors || ! QUnit . isIE ) {
2019-06-26 19:39:10 +00:00
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(div.foo)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(p.foo)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(div#blargh)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not() failing interior" , "#qunit-fixture p:not(p#blargh)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
} else {
2021-04-13 20:11:45 +00:00
// Support: IE 11+
// IE doesn't support `:not(complex selector)`.
2019-06-26 19:39:10 +00:00
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
}
assert . t ( ":not Multiple" , "#qunit-fixture p:not(a)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not Multiple" , "#qunit-fixture p:not( a )" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not Multiple" , "#qunit-fixture p:not( p )" , [ ] ) ;
assert . t ( ":not Multiple" , "p:not(p)" , [ ] ) ;
2021-04-13 20:11:45 +00:00
if ( QUnit . jQuerySelectors || ! QUnit . isIE ) {
2019-06-26 19:39:10 +00:00
assert . t ( ":not Multiple" , "#qunit-fixture p:not(a, b)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not Multiple" , "#qunit-fixture p:not(a, b, div)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( ":not Multiple" , "p:not(a,p)" , [ ] ) ;
assert . t ( ":not Multiple" , "p:not(p,a)" , [ ] ) ;
assert . t ( ":not Multiple" , "p:not(a,p,b)" , [ ] ) ;
} else {
2021-04-13 20:11:45 +00:00
// Support: IE 11+
// IE doesn't support `:not(complex selector)`.
2019-06-26 19:39:10 +00:00
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( ":not Multiple" , ":input:not(:image,:input,:submit)" , [ ] ) ;
assert . t ( ":not Multiple" , "#qunit-fixture p:not(:has(a), :nth-child(1))" , [ "first" ] ) ;
} else {
assert . ok ( "skip" , ":image, :input, :submit not supported in selector-native" ) ;
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
}
assert . t ( "No element not selector" , ".container div:not(.excluded) div" , [ ] ) ;
assert . t ( ":not() Existing attribute" , "#form select:not([multiple])" , [ "select1" , "select2" , "select5" ] ) ;
assert . t ( ":not() Equals attribute" , "#form select:not([name=select1])" , [ "select2" , "select3" , "select4" , "select5" ] ) ;
assert . t ( ":not() Equals quoted attribute" , "#form select:not([name='select1'])" , [ "select2" , "select3" , "select4" , "select5" ] ) ;
assert . t ( ":not() Multiple Class" , "#foo a:not(.blog)" , [ "yahoo" , "anchor2" ] ) ;
assert . t ( ":not() Multiple Class" , "#foo a:not(.link)" , [ "yahoo" , "anchor2" ] ) ;
2021-04-13 20:11:45 +00:00
if ( QUnit . jQuerySelectors || ! QUnit . isIE ) {
2019-06-26 19:39:10 +00:00
assert . t ( ":not() Multiple Class" , "#foo a:not(.blog.link)" , [ "yahoo" , "anchor2" ] ) ;
} else {
2021-04-13 20:11:45 +00:00
// Support: IE 11+
// IE doesn't support `:not(complex selector)`.
2019-06-26 19:39:10 +00:00
assert . ok ( "skip" , ":not(complex selector) not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( ":not chaining (compound)" , "#qunit-fixture div[id]:not(:has(div, span)):not(:has(*))" , [ "nothiddendivchild" , "divWithNoTabIndex" , "fx-tests" ] ) ;
assert . t ( ":not chaining (with attribute)" , "#qunit-fixture form[id]:not([action$='formaction']):not(:button)" , [ "lengthtest" , "name-tests" , "testForm" , "disabled-tests" ] ) ;
assert . t ( ":not chaining (colon in attribute)" , "#qunit-fixture form[id]:not([action='form:action']):not(:button)" , [ "form" , "lengthtest" , "name-tests" , "testForm" , "disabled-tests" ] ) ;
assert . t ( ":not chaining (colon in attribute and nested chaining)" , "#qunit-fixture form[id]:not([action='form:action']:button):not(:input)" , [ "form" , "lengthtest" , "name-tests" , "testForm" , "disabled-tests" ] ) ;
assert . t ( ":not chaining" , "#form select:not(.select1):contains(Nothing) > option:not(option)" , [ ] ) ;
} else {
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
assert . ok ( "skip" , ":button not supported in selector-native" ) ;
assert . ok ( "skip" , ":button not supported in selector-native" ) ;
assert . ok ( "skip" , ":button not supported in selector-native" ) ;
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
2019-06-26 19:39:10 +00:00
assert . t ( "positional :not()" , "#foo p:not(:last)" , [ "sndp" , "en" ] ) ;
assert . t ( "positional :not() prefix" , "#foo p:not(:last) a" , [ "yahoo" ] ) ;
assert . t ( "compound positional :not()" , "#foo p:not(:first, :last)" , [ "en" ] ) ;
assert . t ( "compound positional :not()" , "#foo p:not(:first, :even)" , [ "en" ] ) ;
assert . t ( "compound positional :not()" , "#foo p:not(:first, :odd)" , [ "sap" ] ) ;
assert . t ( "reordered compound positional :not()" , "#foo p:not(:odd, :first)" , [ "sap" ] ) ;
assert . t ( "positional :not() with pre-filter" , "#foo p:not([id]:first)" , [ "en" , "sap" ] ) ;
assert . t ( "positional :not() with post-filter" , "#foo p:not(:first[id])" , [ "en" , "sap" ] ) ;
assert . t ( "positional :not() with pre-filter" , "#foo p:not([lang]:first)" , [ "sndp" , "sap" ] ) ;
assert . t ( "positional :not() with post-filter" , "#foo p:not(:first[lang])" , [ "sndp" , "en" , "sap" ] ) ;
} else {
2019-07-29 19:14:46 +00:00
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
2019-06-26 19:39:10 +00:00
}
} ) ;
2019-07-29 19:14:46 +00:00
QUnit [ QUnit . jQuerySelectorsPos ? "test" : "skip" ] ( "pseudo - position" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 34 ) ;
assert . t ( "First element" , "#qunit-fixture p:first" , [ "firstp" ] ) ;
assert . t ( "First element(case-insensitive)" , "#qunit-fixture p:fiRst" , [ "firstp" ] ) ;
assert . t ( "nth Element" , "#qunit-fixture p:nth(1)" , [ "ap" ] ) ;
assert . t ( "First Element" , "#qunit-fixture p:first" , [ "firstp" ] ) ;
assert . t ( "Last Element" , "p:last" , [ "first" ] ) ;
assert . t ( "Even Elements" , "#qunit-fixture p:even" , [ "firstp" , "sndp" , "sap" ] ) ;
assert . t ( "Odd Elements" , "#qunit-fixture p:odd" , [ "ap" , "en" , "first" ] ) ;
assert . t ( "Position Equals" , "#qunit-fixture p:eq(1)" , [ "ap" ] ) ;
assert . t ( "Position Equals (negative)" , "#qunit-fixture p:eq(-1)" , [ "first" ] ) ;
assert . t ( "Position Greater Than" , "#qunit-fixture p:gt(0)" , [ "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Position Less Than" , "#qunit-fixture p:lt(3)" , [ "firstp" , "ap" , "sndp" ] ) ;
assert . t ( "Position Less Than Big Number" , "#qunit-fixture p:lt(9007199254740991)" , [ "firstp" , "ap" , "sndp" , "en" , "sap" , "first" ] ) ;
assert . t ( "Check position filtering" , "div#nothiddendiv:eq(0)" , [ "nothiddendiv" ] ) ;
assert . t ( "Check position filtering" , "div#nothiddendiv:last" , [ "nothiddendiv" ] ) ;
assert . t ( "Check position filtering" , "div#nothiddendiv:not(:gt(0))" , [ "nothiddendiv" ] ) ;
assert . t ( "Check position filtering" , "#foo > :not(:first)" , [ "en" , "sap" ] ) ;
assert . t ( "Check position filtering" , "#qunit-fixture select > :not(:gt(2))" , [ "option1a" , "option1b" , "option1c" ] ) ;
assert . t ( "Check position filtering" , "#qunit-fixture select:lt(2) :not(:first)" , [ "option1b" , "option1c" , "option1d" , "option2a" , "option2b" , "option2c" , "option2d" ] ) ;
assert . t ( "Check position filtering" , "div.nothiddendiv:eq(0)" , [ "nothiddendiv" ] ) ;
assert . t ( "Check position filtering" , "div.nothiddendiv:last" , [ "nothiddendiv" ] ) ;
assert . t ( "Check position filtering" , "div.nothiddendiv:not(:lt(0))" , [ "nothiddendiv" ] ) ;
assert . t ( "Check element position" , "#qunit-fixture div div:eq(0)" , [ "nothiddendivchild" ] ) ;
assert . t ( "Check element position" , "#select1 option:eq(3)" , [ "option1d" ] ) ;
2019-11-18 21:10:55 +00:00
assert . t ( "Check element position" , "#qunit-fixture div div:eq(10)" , [ "no-clone-exception" ] ) ;
2019-06-26 19:39:10 +00:00
assert . t ( "Check element position" , "#qunit-fixture div div:first" , [ "nothiddendivchild" ] ) ;
assert . t ( "Check element position" , "#qunit-fixture div > div:first" , [ "nothiddendivchild" ] ) ;
assert . t ( "Check element position" , "#qunit-fixture div:first a:first" , [ "yahoo" ] ) ;
assert . t ( "Check element position" , "#qunit-fixture div:first > p:first" , [ "sndp" ] ) ;
assert . t ( "Check element position" , "div#nothiddendiv:first > div:first" , [ "nothiddendivchild" ] ) ;
assert . t ( "Chained pseudo after a pos pseudo" , "#listWithTabIndex li:eq(0):contains(Rice)" , [ "foodWithNegativeTabIndex" ] ) ;
assert . t ( "Check sort order with POS and comma" , "#qunit-fixture em>em>em>em:first-child,div>em:first" , [ "siblingfirst" , "siblinggreatgrandchild" ] ) ;
assert . t ( "Isolated position" , "#qunit-fixture :last" , [ "last" ] ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual (
jQuery ( "#qunit-fixture > p" ) . filter ( "*:lt(2) + *" ) . get ( ) ,
q ( "ap" ) ,
2019-06-26 19:39:10 +00:00
"Seeded pos with trailing relative" ) ;
2022-01-04 15:27:18 +00:00
// jQuery trac-12526
2019-06-26 19:39:10 +00:00
var context = jQuery ( "#qunit-fixture" ) . append ( "<div id='jquery12526'></div>" ) [ 0 ] ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ":last" , context ) . get ( ) , q ( "jquery12526" ) ,
2019-06-26 19:39:10 +00:00
"Post-manipulation positional" ) ;
} ) ;
QUnit . test ( "pseudo - form" , function ( assert ) {
assert . expect ( 16 ) ;
var extraTexts = jQuery ( "<input id=\"impliedText\"/><input id=\"capitalText\" type=\"TEXT\">" ) . appendTo ( "#form" ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Form element :radio" , "#form :radio" , [ "radio1" , "radio2" ] ) ;
assert . t ( "Form element :checkbox" , "#form :checkbox" , [ "check1" , "check2" ] ) ;
assert . t ( "Form element :text" , "#form :text" , [ "text1" , "text2" , "hidden2" , "name" , "impliedText" , "capitalText" ] ) ;
assert . t ( "Form element :radio:checked" , "#form :radio:checked" , [ "radio2" ] ) ;
assert . t ( "Form element :checkbox:checked" , "#form :checkbox:checked" , [ "check1" ] ) ;
assert . t ( "Form element :radio:checked, :checkbox:checked" , "#form :radio:checked, #form :checkbox:checked" , [ "radio2" , "check1" ] ) ;
} else {
assert . ok ( "skip" , ":radio not supported in selector-native" ) ;
assert . ok ( "skip" , ":checkbox not supported in selector-native" ) ;
assert . ok ( "skip" , ":text not supported in selector-native" ) ;
assert . ok ( "skip" , ":radio not supported in selector-native" ) ;
assert . ok ( "skip" , ":checkbox not supported in selector-native" ) ;
assert . ok ( "skip" , ":radio not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Selected option element" ,
"#form option:selected" ,
[ "option1a" , "option2d" , "option3b" , "option3c" , "option4b" , "option4c" , "option4d" ,
"option5a" ] ) ;
assert . t ( "Select options via :selected" , "#select1 option:selected" , [ "option1a" ] ) ;
assert . t ( "Select options via :selected" , "#select2 option:selected" , [ "option2d" ] ) ;
assert . t ( "Select options via :selected" , "#select3 option:selected" , [ "option3b" , "option3c" ] ) ;
assert . t ( "Select options via :selected" , "select[name='select2'] option:selected" , [ "option2d" ] ) ;
} else {
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
assert . ok ( "skip" , ":selected not supported in selector-native" ) ;
}
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . t ( "Form element :input" , "#form :input" , [ "text1" , "text2" , "radio1" , "radio2" , "check1" , "check2" , "hidden1" , "hidden2" , "name" , "search" , "button" , "area1" , "select1" , "select2" , "select3" , "select4" , "select5" , "impliedText" , "capitalText" ] ) ;
// trac-12600
2015-11-10 18:26:15 +00:00
assert . ok (
jQuery ( "<select value='12600'><option value='option' selected='selected'></option><option value=''></option></select>" )
2019-06-26 19:39:10 +00:00
. prop ( "value" , "option" )
. is ( ":input[value='12600']" ) ,
2015-11-10 18:26:15 +00:00
":input[value=foo] selects select by attribute"
) ;
assert . ok ( jQuery ( "<input type='text' value='12600'/>" ) . prop ( "value" , "option" ) . is ( ":input[value='12600']" ) ,
":input[value=foo] selects text input by attribute"
) ;
} else {
assert . ok ( "skip" , ":input not supported in selector-native" ) ;
assert . ok ( "skip" , ":input not supported in selector-native" ) ;
2019-06-26 19:39:10 +00:00
assert . ok ( "skip" , ":input not supported in selector-native" ) ;
2015-11-10 18:26:15 +00:00
}
2012-12-08 21:28:10 +00:00
2019-06-26 19:39:10 +00:00
assert . t ( "Selected option elements are also :checked" , "#form option:checked" ,
[ "option1a" , "option2d" , "option3b" , "option3c" , "option4b" , "option4c" , "option4d" ,
"option5a" ] ) ;
assert . t ( "Hidden inputs are still :enabled" ,
"#hidden1:enabled" ,
[ "hidden1" ] ) ;
2012-12-09 05:26:24 +00:00
2019-06-26 19:39:10 +00:00
extraTexts . remove ( ) ;
} ) ;
QUnit . test ( "pseudo - :(dis|en)abled, explicitly disabled" , function ( assert ) {
assert . expect ( 2 ) ;
// Set a meaningless disabled property on a common ancestor
var container = document . getElementById ( "disabled-tests" ) ;
container . disabled = true ;
// Support: IE 6 - 11
// Unset the property where it is not meaningless
if ( document . getElementById ( "enabled-input" ) . isDisabled ) {
container . disabled = undefined ;
}
assert . t (
"Explicitly disabled elements" ,
"#enabled-fieldset :disabled" ,
[ "disabled-input" , "disabled-textarea" , "disabled-button" ,
"disabled-select" , "disabled-optgroup" , "disabled-option" ]
2012-12-09 05:26:24 +00:00
) ;
2019-06-26 19:39:10 +00:00
2023-02-13 17:34:41 +00:00
assert . t (
"Enabled elements" ,
"#enabled-fieldset :enabled" ,
[ "enabled-input" , "enabled-textarea" , "enabled-button" ,
"enabled-select" , "enabled-optgroup" , "enabled-option" ]
) ;
2019-06-26 19:39:10 +00:00
} ) ;
QUnit . test ( "pseudo - :(dis|en)abled, optgroup and option" , function ( assert ) {
assert . expect ( 2 ) ;
assert . t (
":disabled" ,
"#disabled-select-inherit :disabled, #enabled-select-inherit :disabled" ,
[ "disabled-optgroup-inherit" , "disabled-optgroup-option" , "en_disabled-optgroup-inherit" ,
"en_disabled-optgroup-option" ]
) ;
assert . t (
":enabled" ,
"#disabled-select-inherit :enabled, #enabled-select-inherit :enabled" ,
[ "enabled-optgroup-inherit" , "enabled-optgroup-option" , "enabled-select-option" ]
) ;
} ) ;
QUnit . test ( "pseudo - fieldset:(dis|en)abled" , function ( assert ) {
assert . expect ( 2 ) ;
assert . t ( "Disabled fieldset" , "fieldset:disabled" , [ "disabled-fieldset" ] ) ;
assert . t ( "Enabled fieldset" , "fieldset:enabled" , [ "enabled-fieldset" ] ) ;
} ) ;
QUnit . test ( "pseudo - :disabled by ancestry" , function ( assert ) {
assert . expect ( 1 ) ;
assert . t (
"Inputs inherit disabled from fieldset" ,
"#disabled-fieldset :disabled" ,
[ "disabled-fieldset-input" , "disabled-fieldset-textarea" ,
"disabled-fieldset-button" ]
2012-12-09 05:26:24 +00:00
) ;
2015-08-16 06:59:58 +00:00
} ) ;
2012-05-30 17:46:50 +00:00
2019-08-26 17:15:53 +00:00
QUnit . test ( "pseudo - a:(dis|en)abled" , function ( assert ) {
assert . expect ( 2 ) ;
var enabled , disabled ,
2020-03-16 20:49:29 +00:00
container = jQuery ( "<div></div>" ) ,
2019-08-26 17:15:53 +00:00
anchor = jQuery ( "<a href='#'>Link</a>" ) ;
container . appendTo ( "#qunit-fixture" ) ;
enabled = container . find ( "a:enabled" ) ;
disabled = container . find ( "a:disabled" ) ;
assert . strictEqual ( enabled . length , 0 , ":enabled doesn't match anchor elements" ) ;
assert . strictEqual ( disabled . length , 0 , ":disabled doesn't match anchor elements" ) ;
} ) ;
2019-06-26 19:39:10 +00:00
QUnit . test ( "pseudo - :target and :root" , function ( assert ) {
assert . expect ( 2 ) ;
// Target
var oldHash ,
2020-03-16 20:49:29 +00:00
$link = jQuery ( "<a></a>" ) . attr ( {
2019-06-26 19:39:10 +00:00
href : "#" ,
id : "new-link"
} ) . appendTo ( "#qunit-fixture" ) ;
oldHash = window . location . hash ;
window . location . hash = "new-link" ;
assert . t ( ":target" , ":target" , [ "new-link" ] ) ;
$link . remove ( ) ;
window . location . hash = oldHash ;
// Root
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( ":root" ) [ 0 ] , document . documentElement , ":root selector" ) ;
2019-06-26 19:39:10 +00:00
} ) ;
QUnit . test ( "pseudo - :lang" , function ( assert ) {
2023-06-27 16:05:46 +00:00
assert . expect ( QUnit . jQuerySelectors ? 104 : 54 ) ;
2019-06-26 19:39:10 +00:00
var docElem = document . documentElement ,
docXmlLang = docElem . getAttribute ( "xml:lang" ) ,
docLang = docElem . lang ,
foo = document . getElementById ( "foo" ) ,
anchor = document . getElementById ( "anchor2" ) ,
xml = createWithFriesXML ( ) ,
testLang = function ( text , elem , container , lang , extra ) {
var message ,
full = lang + "-" + extra ;
message = "lang=" + lang + " " + text ;
container . setAttribute ( container . ownerDocument . documentElement . nodeName === "HTML" ? "lang" : "xml:lang" , lang ) ;
assertMatch ( message , elem , ":lang(" + lang + ")" ) ;
assertMatch ( message , elem , ":lang(" + mixCase ( lang ) + ")" ) ;
assertNoMatch ( message , elem , ":lang(" + full + ")" ) ;
assertNoMatch ( message , elem , ":lang(" + mixCase ( full ) + ")" ) ;
assertNoMatch ( message , elem , ":lang(" + lang + "-)" ) ;
assertNoMatch ( message , elem , ":lang(" + full + "-)" ) ;
assertNoMatch ( message , elem , ":lang(" + lang + "glish)" ) ;
assertNoMatch ( message , elem , ":lang(" + full + "glish)" ) ;
message = "lang=" + full + " " + text ;
container . setAttribute ( container . ownerDocument . documentElement . nodeName === "HTML" ? "lang" : "xml:lang" , full ) ;
assertMatch ( message , elem , ":lang(" + lang + ")" ) ;
assertMatch ( message , elem , ":lang(" + mixCase ( lang ) + ")" ) ;
assertMatch ( message , elem , ":lang(" + full + ")" ) ;
assertMatch ( message , elem , ":lang(" + mixCase ( full ) + ")" ) ;
assertNoMatch ( message , elem , ":lang(" + lang + "-)" ) ;
assertNoMatch ( message , elem , ":lang(" + full + "-)" ) ;
assertNoMatch ( message , elem , ":lang(" + lang + "glish)" ) ;
assertNoMatch ( message , elem , ":lang(" + full + "glish)" ) ;
} ,
mixCase = function ( str ) {
var ret = str . split ( "" ) ,
i = ret . length ;
while ( i -- ) {
if ( i & 1 ) {
ret [ i ] = ret [ i ] . toUpperCase ( ) ;
}
}
return ret . join ( "" ) ;
} ,
assertMatch = function ( text , elem , selector ) {
assert . ok ( jQuery ( elem ) . is ( selector ) , text + " match " + selector ) ;
} ,
assertNoMatch = function ( text , elem , selector ) {
assert . ok ( ! jQuery ( elem ) . is ( selector ) , text + " fail " + selector ) ;
} ;
// Prefixing and inheritance
assert . ok ( jQuery ( docElem ) . is ( ":lang(" + docElem . lang + ")" ) , "starting :lang" ) ;
testLang ( "document" , anchor , docElem , "en" , "us" ) ;
testLang ( "grandparent" , anchor , anchor . parentNode . parentNode , "yue" , "hk" ) ;
assert . ok ( ! jQuery ( anchor ) . is ( ":lang(en), :lang(en-us)" ) ,
":lang does not look above an ancestor with specified lang" ) ;
testLang ( "self" , anchor , anchor , "es" , "419" ) ;
assert . ok (
! jQuery ( anchor ) . is ( ":lang(en), :lang(en-us), :lang(yue), :lang(yue-hk)" ) ,
":lang does not look above self with specified lang"
) ;
// Searching by language tag
anchor . parentNode . parentNode . lang = "arab" ;
anchor . parentNode . lang = anchor . parentNode . id = "ara-sa" ;
anchor . lang = "ara" ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ":lang(ara)" , foo ) . get ( ) , [ anchor . parentNode , anchor ] , "Find by :lang" ) ;
2019-06-26 19:39:10 +00:00
// Selector validity
anchor . parentNode . lang = "ara" ;
anchor . lang = "ara\\b" ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( ":lang(ara\\b)" , foo ) . get ( ) , [ ] , ":lang respects backslashes" ) ;
2023-06-27 16:05:46 +00:00
// Support: Firefox 114+
// Firefox 114+ no longer match on backslashes in `:lang()`, even when escaped.
// It is an intentional change as `:lang()` parameters are supposed to be valid
// BCP 47 strings. Therefore, we won't attempt to patch it.
// We'll keep this test here until other browsers match the behavior.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1839747#c1
// See https://github.com/w3c/csswg-drafts/issues/8720#issuecomment-1509242961
//
// assert.deepEqual( jQuery( ":lang(ara\\\\b)", foo ).get(), [ anchor ],
// ":lang respects escaped backslashes" );
2019-06-26 19:39:10 +00:00
assert . throws ( function ( ) {
2019-10-21 17:02:22 +00:00
jQuery ( "#qunit-fixture:lang(c++)" ) ;
2019-06-26 19:39:10 +00:00
} , ":lang value must be a valid identifier" ) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
// XML
foo = jQuery ( "response" , xml ) [ 0 ] ;
anchor = jQuery ( "#seite1" , xml ) [ 0 ] ;
testLang ( "XML document" , anchor , xml . documentElement , "en" , "us" ) ;
testLang ( "XML grandparent" , anchor , foo , "yue" , "hk" ) ;
assert . ok ( ! jQuery ( anchor ) . is ( ":lang(en), :lang(en-us)" ) ,
"XML :lang does not look above an ancestor with specified lang" ) ;
testLang ( "XML self" , anchor , anchor , "es" , "419" ) ;
assert . ok (
! jQuery ( anchor ) . is ( ":lang(en), :lang(en-us), :lang(yue), :lang(yue-hk)" ) ,
"XML :lang does not look above self with specified lang" ) ;
}
// Cleanup
if ( docXmlLang == null ) {
docElem . removeAttribute ( "xml:lang" ) ;
} else {
docElem . setAttribute ( "xml:lang" , docXmlLang ) ;
}
docElem . lang = docLang ;
} ) ;
QUnit . test ( "context" , function ( assert ) {
assert . expect ( 21 ) ;
var context ,
selector = ".blog" ,
expected = q ( "mark" , "simon" ) ,
iframe = document . getElementById ( "iframe" ) ,
iframeDoc = iframe . contentDocument || iframe . contentWindow . document ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( selector , document ) . get ( ) , expected , "explicit document context" ) ;
assert . deepEqual ( jQuery ( selector ) . get ( ) , expected , "unspecified context becomes document" ) ;
assert . deepEqual ( jQuery ( selector , undefined ) . get ( ) , expected ,
2019-06-26 19:39:10 +00:00
"undefined context becomes document" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( selector , null ) . get ( ) , expected , "null context becomes document" ) ;
2019-06-26 19:39:10 +00:00
iframeDoc . open ( ) ;
iframeDoc . write ( "<body><p id='foo'>bar</p></body>" ) ;
iframeDoc . close ( ) ;
expected = [ iframeDoc . getElementById ( "foo" ) ] ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "p" , iframeDoc ) . get ( ) , expected , "Other document context (simple)" ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "p:contains(ar)" , iframeDoc ) . get ( ) , expected ,
2019-06-26 19:39:10 +00:00
"Other document context (complex)" ) ;
} else {
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
}
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "span" , iframeDoc ) . get ( ) , [ ] ,
2019-06-26 19:39:10 +00:00
"Other document context (simple, no results)" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "* span" , iframeDoc ) . get ( ) , [ ] ,
2019-06-26 19:39:10 +00:00
"Other document context (complex, no results)" ) ;
context = document . getElementById ( "nothiddendiv" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "*" , context ) . get ( ) , q ( "nothiddendivchild" ) , "<div> context" ) ;
2019-06-26 19:39:10 +00:00
2023-02-13 17:34:41 +00:00
assert . deepEqual ( jQuery ( "* > *" , context ) . get ( ) , [ ] , "<div> context (no results)" ) ;
2019-06-26 19:39:10 +00:00
context . removeAttribute ( "id" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "*" , context ) . get ( ) , q ( "nothiddendivchild" ) , "no-id element context" ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "* > *" , context ) . get ( ) , [ ] , "no-id element context (no results)" ) ;
2019-06-26 19:39:10 +00:00
} else {
assert . ok ( "skip" , ":contains not supported in selector-native" ) ;
}
assert . strictEqual ( context . getAttribute ( "id" ) || "" , "" , "id not added by no-id selection" ) ;
context = document . getElementById ( "lengthtest" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "input" , context ) . get ( ) , q ( "length" , "idTest" ) , "<form> context" ) ;
assert . deepEqual ( jQuery ( "select" , context ) . get ( ) , [ ] , "<form> context (no results)" ) ;
2019-06-26 19:39:10 +00:00
context = document . getElementById ( "台北Táiběi" ) ;
expected = q ( "台北Táiběi-child" ) ;
2019-10-21 17:02:22 +00:00
assert . deepEqual ( jQuery ( "span[id]" , context ) . get ( ) , expected , "context with non-ASCII id" ) ;
assert . deepEqual ( jQuery ( "#台北Táiběi span[id]" , context . parentNode ) . get ( ) , expected ,
2019-06-26 19:39:10 +00:00
"context with non-ASCII id selector prefix" ) ;
context = document . createDocumentFragment ( ) ;
// Capture *independent* expected nodes before they're detached from the page
expected = q ( "siblingnext" , "siblingspan" ) ;
context . appendChild ( document . getElementById ( "siblingTest" ) ) ;
2023-02-13 17:34:41 +00:00
assert . deepEqual (
jQuery ( "em:nth-child(2)" , context ) . get ( ) ,
expected . slice ( 0 , 1 ) ,
"DocumentFragment context"
) ;
assert . deepEqual ( jQuery ( "span" , context ) . get ( ) , expected . slice ( 1 ) ,
"DocumentFragment context by tag name" ) ;
assert . deepEqual ( jQuery ( "p" , context ) . get ( ) , [ ] , "DocumentFragment context (no results)" ) ;
2019-06-26 19:39:10 +00:00
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectors ) {
2019-06-26 19:39:10 +00:00
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( "em + :not(:has(*)):not(:empty), foo" , context . firstChild ) . get ( ) ,
2019-06-26 19:39:10 +00:00
expected . slice ( 0 , 1 ) ,
2022-01-04 15:27:18 +00:00
"Non-qSA path correctly sets detached context for sibling selectors (jQuery trac-14351)"
2019-06-26 19:39:10 +00:00
) ;
} else {
assert . ok ( "skip" , ":has not supported in selector-native" ) ;
}
} ) ;
2020-09-22 15:49:28 +00:00
// Support: IE 11+
// IE doesn't support the :scope pseudo-class so it will trigger MutationObservers.
2019-08-19 16:41:03 +00:00
// The test is skipped there.
2020-09-22 15:49:28 +00:00
QUnit . testUnlessIE ( "selectors maintaining context don't trigger mutation observers" , function ( assert ) {
2019-08-19 16:41:03 +00:00
assert . expect ( 1 ) ;
var timeout ,
done = assert . async ( ) ,
2020-03-16 20:49:29 +00:00
container = jQuery ( "<div></div>" ) ,
child = jQuery ( "<div></div>" ) ;
2019-08-19 16:41:03 +00:00
child . appendTo ( container ) ;
container . appendTo ( "#qunit-fixture" ) ;
var observer = new MutationObserver ( function ( ) {
clearTimeout ( timeout ) ;
observer . disconnect ( ) ;
assert . ok ( false , "Mutation observer fired during selection" ) ;
done ( ) ;
} ) ;
observer . observe ( container [ 0 ] , { attributes : true } ) ;
container . find ( "div div" ) ;
timeout = setTimeout ( function ( ) {
observer . disconnect ( ) ;
assert . ok ( true , "Mutation observer didn't fire during selection" ) ;
done ( ) ;
} ) ;
} ) ;
2019-06-26 19:39:10 +00:00
QUnit . test ( "caching does not introduce bugs" , function ( assert ) {
assert . expect ( 3 ) ;
var sap = document . getElementById ( "sap" ) ;
2019-10-21 17:02:22 +00:00
jQuery ( ":not(code)" , document . getElementById ( "ap" ) ) ;
2019-06-26 19:39:10 +00:00
assert . deepEqual (
2019-10-21 17:02:22 +00:00
jQuery ( ":not(code)" , document . getElementById ( "foo" ) ) . get ( ) ,
2019-06-26 19:39:10 +00:00
q ( "sndp" , "en" , "yahoo" , "sap" , "anchor2" , "simon" ) ,
"Reusing selector with new context"
) ;
2019-07-29 19:14:46 +00:00
if ( QUnit . jQuerySelectorsPos ) {
2022-01-04 15:27:18 +00:00
assert . t ( "Deep ancestry caching in post-positional element matcher (jQuery trac-14657)" ,
2019-06-26 19:39:10 +00:00
"#qunit-fixture a:lt(3):parent" ,
[ "simon1" , "google" , "groups" ] ) ;
} else {
2019-07-29 19:14:46 +00:00
assert . ok ( "skip" , "Positional selectors are not supported" ) ;
2019-06-26 19:39:10 +00:00
}
sap . className = "original" ;
2019-10-21 17:02:22 +00:00
jQuery ( "#qunit-fixture .original" ) ;
2019-06-26 19:39:10 +00:00
document . getElementById ( "nothiddendiv" ) . appendChild (
sap . cloneNode ( true ) ) . className = "clone" ;
2019-10-21 17:02:22 +00:00
assert . equal ( jQuery ( "#qunit-fixture .clone [href*='2']" ) . length , 1 ,
2019-06-26 19:39:10 +00:00
"Cloning does not poison caches" ) ;
} ) ;
2015-08-16 06:59:58 +00:00
QUnit . test ( "disconnected nodes" , function ( assert ) {
2015-08-16 03:45:28 +00:00
assert . expect ( 1 ) ;
2013-02-19 04:52:29 +00:00
2020-03-16 20:49:29 +00:00
var $div = jQuery ( "<div></div>" ) ;
2015-08-16 06:59:58 +00:00
assert . equal ( $div . is ( "div" ) , true , "Make sure .is('nodeName') works on disconnected nodes." ) ;
} ) ;
2013-02-19 04:52:29 +00:00
2019-07-29 19:14:46 +00:00
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "disconnected nodes" , function ( assert ) {
2015-08-16 03:45:28 +00:00
assert . expect ( 3 ) ;
2013-02-19 04:52:29 +00:00
2015-08-16 06:59:58 +00:00
var $opt = jQuery ( "<option></option>" ) . attr ( "value" , "whipit" ) . appendTo ( "#qunit-fixture" ) . detach ( ) ;
2015-08-16 03:45:28 +00:00
assert . equal ( $opt . val ( ) , "whipit" , "option value" ) ;
2015-08-16 06:59:58 +00:00
assert . equal ( $opt . is ( ":selected" ) , false , "unselected option" ) ;
$opt . prop ( "selected" , true ) ;
assert . equal ( $opt . is ( ":selected" ) , true , "selected option" ) ;
} ) ;
2012-05-28 16:18:40 +00:00
2020-09-22 15:49:28 +00:00
// Support: IE 11+
// IE doesn't support Shadow DOM.
2023-02-13 17:34:41 +00:00
QUnit . testUnlessIE ( "Shadow DOM nodes supported as root" , function ( assert ) {
2019-06-26 19:39:10 +00:00
assert . expect ( 2 ) ;
2020-03-16 20:49:29 +00:00
var shadowHost = jQuery ( "<div></div>" ) . appendTo ( "#qunit-fixture" ) [ 0 ] ;
2019-06-26 19:39:10 +00:00
var shadowRoot = shadowHost . attachShadow ( { mode : "open" } ) ;
shadowRoot . innerHTML = "<div class='vagabond'><p></p></div>" ;
assert . equal ( jQuery ( shadowRoot ) . find ( ".vagabond" ) . length , 1 ,
"Selection by class with shadow root" ) ;
assert . equal ( jQuery ( shadowRoot ) . find ( "p" ) . length , 1 ,
"Paragraph element selected from shadow root" ) ;
} ) ;
2016-04-10 19:42:44 +00:00
testIframe (
2015-08-16 03:45:28 +00:00
"attributes - jQuery.attr" ,
2016-04-08 16:00:17 +00:00
"selector/html5_selector.html" ,
2016-04-10 19:42:44 +00:00
function ( assert , jQuery , window , document ) {
2015-08-16 03:45:28 +00:00
assert . expect ( 38 ) ;
/ * *
* Returns an array of elements with the given IDs
* q & t are added here for the iFrame ' s context
* /
function q ( ) {
var r = [ ] ,
i = 0 ;
for ( ; i < arguments . length ; i ++ ) {
2015-08-16 06:59:58 +00:00
r . push ( document . getElementById ( arguments [ i ] ) ) ;
2015-08-16 03:45:28 +00:00
}
return r ;
2011-10-13 15:11:41 +00:00
}
2012-02-23 20:48:12 +00:00
2015-08-16 03:45:28 +00:00
/ * *
* Asserts that a select matches the given IDs
2015-09-18 16:59:48 +00:00
* @ example t ( "Check for something" , "//[a]" , [ "foo" , "bar" ] ) ;
2019-06-26 19:39:10 +00:00
* @ param { String } message - Assertion name
* @ param { String } selector - jQuery selector
* @ param { Array } expectedIds - Array of ids to construct what is expected
2015-08-16 03:45:28 +00:00
* /
2019-06-26 19:39:10 +00:00
function t ( message , selector , expectedIds ) {
var elems = jQuery ( selector ) . get ( ) ;
2015-08-16 03:45:28 +00:00
2019-06-26 19:39:10 +00:00
assert . deepEqual ( elems , q . apply ( q , expectedIds ) , message + " (" + selector + ")" ) ;
2011-09-12 23:40:14 +00:00
}
2015-08-16 03:45:28 +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)
2015-08-16 06:59:58 +00:00
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" ] ) ;
t ( "Attribute Exists" , "[loop]" , [ "video1" ] ) ;
t ( "Attribute Exists" , "[multiple]" , [ "select1" ] ) ;
t ( "Attribute Exists" , "[muted]" , [ "audio1" ] ) ;
t ( "Attribute Exists" , "[nohref]" , [ "area1" ] ) ;
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" ] ) ;
t ( "Attribute Exists" , "[selected]" , [ "option1" ] ) ;
t ( "Attribute Exists" , "[truespeed]" , [ "marquee1" ] ) ;
2015-08-16 03:45:28 +00:00
// Enumerated attributes (these are not boolean content attributes)
jQuery . expandedEach = jQuery . each ;
2015-08-16 06:59:58 +00:00
jQuery . expandedEach ( [ "draggable" , "contenteditable" , "aria-disabled" ] , function ( i , val ) {
t ( "Enumerated attribute" , "[" + val + "]" , [ "div1" ] ) ;
} ) ;
t ( "Enumerated attribute" , "[spellcheck]" , [ "span1" ] ) ;
2015-08-16 03:45:28 +00:00
2022-01-04 15:27:18 +00:00
t ( "tabindex selector does not retrieve all elements in IE6/7 (trac-8473)" ,
2015-08-16 03:45:28 +00:00
"form, [tabindex]" , [ "form1" , "text1" ] ) ;
2022-01-04 15:27:18 +00:00
t ( "Improperly named form elements do not interfere with form selections (trac-9570)" , "form[name='formName']" , [ "form1" ] ) ;
2011-10-13 15:11:41 +00:00
}
2015-08-16 03:45:28 +00:00
) ;
2011-09-12 23:40:14 +00:00
2022-11-21 22:23:39 +00:00
QUnit . test ( "find in document fragments" , function ( assert ) {
assert . expect ( 1 ) ;
var elem ,
nonnodes = jQuery ( "#nonnodes" ) . contents ( ) ,
fragment = document . createDocumentFragment ( ) ;
nonnodes . each ( function ( ) {
fragment . appendChild ( this ) ;
} ) ;
elem = jQuery ( fragment ) . find ( "#nonnodesElement" ) ;
assert . strictEqual ( elem . length , 1 , "Selection works" ) ;
} ) ;
2022-11-28 17:10:33 +00:00
function getUniqueSortFixtures ( ) {
var i ,
2014-02-26 23:01:48 +00:00
detached = [ ] ,
body = document . body ,
2015-08-16 06:59:58 +00:00
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" ) ) ;
2014-02-26 23:01:48 +00:00
for ( i = 0 ; i < 12 ; i ++ ) {
2015-08-16 06:59:58 +00:00
detached . push ( document . createElement ( "li" ) ) ;
detached [ i ] . id = "detached" + i ;
detached2 . appendChild ( document . createElement ( "li" ) ) . id = "detachedChild" + i ;
2014-02-26 23:01:48 +00:00
}
2022-11-28 17:10:33 +00:00
return {
2014-02-26 23:01:48 +00:00
"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 : [
2019-06-26 19:39:10 +00:00
detached2 . childNodes [ 3 ] ,
2015-08-16 06:59:58 +00:00
detached2 . childNodes [ 0 ] ,
detached2 . childNodes [ 2 ] ,
2019-06-26 19:39:10 +00:00
detached2 . childNodes [ 1 ]
2014-02-26 23:01:48 +00:00
] ,
expected : [
2015-08-16 06:59:58 +00:00
detached2 . childNodes [ 0 ] ,
detached2 . childNodes [ 1 ] ,
detached2 . childNodes [ 2 ] ,
detached2 . childNodes [ 3 ]
2014-02-26 23:01:48 +00:00
]
} ,
"Attached/detached mixture" : {
input : [ detached1 , fixture , detached2 , document , detachedChild , body , detachedGrandchild ] ,
expected : [ document , body , fixture ] ,
length : 3
}
} ;
2022-11-28 17:10:33 +00:00
}
QUnit . test ( "jQuery.uniqueSort" , function ( assert ) {
assert . expect ( 14 ) ;
2014-02-26 23:01:48 +00:00
2022-11-28 17:10:33 +00:00
var fixtures = getUniqueSortFixtures ( ) ;
function Arrayish ( arr ) {
var i = this . length = arr . length ;
while ( i -- ) {
this [ i ] = arr [ i ] ;
}
}
Arrayish . prototype = {
sliceForTestOnly : [ ] . slice
} ;
jQuery . each ( fixtures , function ( label , fixture ) {
var length = fixture . length || fixture . input . length ;
// We duplicate `fixture.input` because otherwise it is modified by `uniqueSort`
2022-01-24 17:55:16 +00:00
// and the second test becomes worthless.
2022-11-28 17:10:33 +00:00
assert . deepEqual (
jQuery . uniqueSort ( fixture . input . slice ( 0 ) )
. slice ( 0 , length ) ,
fixture . expected ,
label + " (array)"
) ;
assert . deepEqual (
jQuery . uniqueSort ( new Arrayish ( fixture . input ) )
. sliceForTestOnly ( 0 , length ) ,
fixture . expected ,
label + " (quasi-array)"
) ;
} ) ;
} ) ;
QUnit . test ( "uniqueSort()" , function ( assert ) {
assert . expect ( 28 ) ;
var fixtures = getUniqueSortFixtures ( ) ;
jQuery . each ( fixtures , function ( label , fixture ) {
var length = fixture . length || fixture . input . length ,
fixtureInputCopy = fixture . input . slice ( 0 ) ,
sortedElem = jQuery ( fixture . input ) . uniqueSort ( ) ;
assert . deepEqual ( fixture . input , fixtureInputCopy , "Fixture not modified (" + label + ")" ) ;
assert . deepEqual ( sortedElem . slice ( 0 , length ) . toArray ( ) , fixture . expected , label ) ;
// Chaining
assert . ok ( sortedElem instanceof jQuery , "chaining" ) ;
assert . deepEqual ( sortedElem . end ( ) . toArray ( ) , fixture . input , label ) ;
2015-08-16 06:59:58 +00:00
} ) ;
} ) ;
2014-02-26 23:01:48 +00:00
2016-04-10 19:42:44 +00:00
testIframe (
2019-06-26 19:39:10 +00:00
"jQuery.uniqueSort works cross-window (trac-14381)" ,
"selector/mixed_sort.html" ,
function ( assert , jQuery , window , document , actual , expected ) {
assert . expect ( 1 ) ;
assert . deepEqual ( actual , expected , "Mixed array was sorted correctly" ) ;
}
) ;
testIframe (
"jQuery selector cache collides with multiple jQueries on a page" ,
2019-07-29 19:14:46 +00:00
"selector/cache.html" ,
2016-04-10 19:42:44 +00:00
function ( assert , jQuery , window , document ) {
2016-05-10 09:12:28 +00:00
var $cached = window . $cached ;
2015-08-16 03:45:28 +00:00
2015-08-16 06:59:58 +00:00
assert . expect ( 4 ) ;
2015-08-16 03:45:28 +00:00
assert . notStrictEqual ( jQuery , $cached , "Loaded two engines" ) ;
2015-08-16 06:59:58 +00:00
assert . deepEqual ( $cached ( ".test a" ) . get ( ) , [ document . getElementById ( "collision" ) ] , "Select collision anchor with first sizzle" ) ;
assert . equal ( jQuery ( ".evil a" ) . length , 0 , "Select nothing with second sizzle" ) ;
assert . equal ( jQuery ( ".evil a" ) . length , 0 , "Select nothing again with second sizzle" ) ;
2015-08-16 03:45:28 +00:00
}
) ;
2014-02-24 18:05:16 +00:00
2022-01-04 15:27:18 +00:00
QUnit . test ( "Iframe dispatch should not affect jQuery (trac-13936)" , function ( assert ) {
2019-02-18 18:02:38 +00:00
assert . expect ( 1 ) ;
2014-02-24 18:05:16 +00:00
var loaded = false ,
thrown = false ,
2014-05-29 17:45:59 +00:00
iframe = document . getElementById ( "iframe" ) ,
2019-02-18 18:02:38 +00:00
iframeDoc = iframe . contentDocument || iframe . contentWindow . document ,
done = assert . async ( ) ;
2014-02-24 18:05:16 +00:00
jQuery ( iframe ) . on ( "load" , function ( ) {
var form ;
try {
iframeDoc = this . contentDocument || this . contentWindow . document ;
2014-05-29 17:54:45 +00:00
form = jQuery ( "#navigate" , iframeDoc ) [ 0 ] ;
2014-02-24 18:05:16 +00:00
} catch ( e ) {
thrown = e ;
}
if ( loaded ) {
2015-08-16 03:45:28 +00:00
assert . strictEqual ( thrown , false , "No error thrown from post-reload jQuery call" ) ;
2014-05-29 17:54:45 +00:00
// clean up
jQuery ( iframe ) . off ( ) ;
2019-02-18 18:02:38 +00:00
done ( ) ;
2014-02-24 18:05:16 +00:00
} else {
loaded = true ;
form . submit ( ) ;
}
2015-08-16 06:59:58 +00:00
} ) ;
2014-02-24 18:05:16 +00:00
iframeDoc . open ( ) ;
2014-05-29 17:45:59 +00:00
iframeDoc . write ( "<body><form id='navigate' action='?'></form></body>" ) ;
2014-02-24 18:05:16 +00:00
iframeDoc . close ( ) ;
2015-08-16 06:59:58 +00:00
} ) ;
2016-01-27 17:57:04 +00:00
2019-06-26 19:39:10 +00:00
QUnit . test ( "jQuery.escapeSelector" , function ( assert ) {
assert . expect ( 58 ) ;
// Edge cases
assert . equal ( jQuery . escapeSelector ( ) , "undefined" , "Converts undefined to string" ) ;
assert . equal ( jQuery . escapeSelector ( "-" ) , "\\-" , "Escapes standalone dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-a" ) , "-a" , "Doesn't escape leading dash followed by non-number" ) ;
assert . equal ( jQuery . escapeSelector ( "--" ) , "--" , "Doesn't escape standalone double dash" ) ;
assert . equal ( jQuery . escapeSelector ( "\uFFFD" ) , "\uFFFD" ,
"Doesn't escape standalone replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "a\uFFFD" ) , "a\uFFFD" ,
"Doesn't escape trailing replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "\uFFFDb" ) , "\uFFFDb" ,
"Doesn't escape leading replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "a\uFFFDb" ) , "a\uFFFDb" ,
"Doesn't escape embedded replacement character" ) ;
// Derived from CSSOM tests
// https://test.csswg.org/harness/test/cssom-1_dev/section/7.1/
// String conversion
assert . equal ( jQuery . escapeSelector ( true ) , "true" , "Converts boolean true to string" ) ;
assert . equal ( jQuery . escapeSelector ( false ) , "false" , "Converts boolean true to string" ) ;
assert . equal ( jQuery . escapeSelector ( null ) , "null" , "Converts null to string" ) ;
assert . equal ( jQuery . escapeSelector ( "" ) , "" , "Doesn't modify empty string" ) ;
// Null bytes
assert . equal ( jQuery . escapeSelector ( "\0" ) , "\uFFFD" ,
"Escapes null-character input as replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "a\0" ) , "a\uFFFD" ,
"Escapes trailing-null input as replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "\0b" ) , "\uFFFDb" ,
"Escapes leading-null input as replacement character" ) ;
assert . equal ( jQuery . escapeSelector ( "a\0b" ) , "a\uFFFDb" ,
"Escapes embedded-null input as replacement character" ) ;
// Number prefix
assert . equal ( jQuery . escapeSelector ( "0a" ) , "\\30 a" , "Escapes leading 0" ) ;
assert . equal ( jQuery . escapeSelector ( "1a" ) , "\\31 a" , "Escapes leading 1" ) ;
assert . equal ( jQuery . escapeSelector ( "2a" ) , "\\32 a" , "Escapes leading 2" ) ;
assert . equal ( jQuery . escapeSelector ( "3a" ) , "\\33 a" , "Escapes leading 3" ) ;
assert . equal ( jQuery . escapeSelector ( "4a" ) , "\\34 a" , "Escapes leading 4" ) ;
assert . equal ( jQuery . escapeSelector ( "5a" ) , "\\35 a" , "Escapes leading 5" ) ;
assert . equal ( jQuery . escapeSelector ( "6a" ) , "\\36 a" , "Escapes leading 6" ) ;
assert . equal ( jQuery . escapeSelector ( "7a" ) , "\\37 a" , "Escapes leading 7" ) ;
assert . equal ( jQuery . escapeSelector ( "8a" ) , "\\38 a" , "Escapes leading 8" ) ;
assert . equal ( jQuery . escapeSelector ( "9a" ) , "\\39 a" , "Escapes leading 9" ) ;
// Letter-number prefix
assert . equal ( jQuery . escapeSelector ( "a0b" ) , "a0b" , "Doesn't escape embedded 0" ) ;
assert . equal ( jQuery . escapeSelector ( "a1b" ) , "a1b" , "Doesn't escape embedded 1" ) ;
assert . equal ( jQuery . escapeSelector ( "a2b" ) , "a2b" , "Doesn't escape embedded 2" ) ;
assert . equal ( jQuery . escapeSelector ( "a3b" ) , "a3b" , "Doesn't escape embedded 3" ) ;
assert . equal ( jQuery . escapeSelector ( "a4b" ) , "a4b" , "Doesn't escape embedded 4" ) ;
assert . equal ( jQuery . escapeSelector ( "a5b" ) , "a5b" , "Doesn't escape embedded 5" ) ;
assert . equal ( jQuery . escapeSelector ( "a6b" ) , "a6b" , "Doesn't escape embedded 6" ) ;
assert . equal ( jQuery . escapeSelector ( "a7b" ) , "a7b" , "Doesn't escape embedded 7" ) ;
assert . equal ( jQuery . escapeSelector ( "a8b" ) , "a8b" , "Doesn't escape embedded 8" ) ;
assert . equal ( jQuery . escapeSelector ( "a9b" ) , "a9b" , "Doesn't escape embedded 9" ) ;
// Dash-number prefix
assert . equal ( jQuery . escapeSelector ( "-0a" ) , "-\\30 a" , "Escapes 0 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-1a" ) , "-\\31 a" , "Escapes 1 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-2a" ) , "-\\32 a" , "Escapes 2 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-3a" ) , "-\\33 a" , "Escapes 3 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-4a" ) , "-\\34 a" , "Escapes 4 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-5a" ) , "-\\35 a" , "Escapes 5 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-6a" ) , "-\\36 a" , "Escapes 6 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-7a" ) , "-\\37 a" , "Escapes 7 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-8a" ) , "-\\38 a" , "Escapes 8 after leading dash" ) ;
assert . equal ( jQuery . escapeSelector ( "-9a" ) , "-\\39 a" , "Escapes 9 after leading dash" ) ;
// Double dash prefix
assert . equal ( jQuery . escapeSelector ( "--a" ) , "--a" , "Doesn't escape leading double dash" ) ;
// Miscellany
assert . equal ( jQuery . escapeSelector ( "\x01\x02\x1E\x1F" ) , "\\1 \\2 \\1e \\1f " ,
"Escapes C0 control characters" ) ;
assert . equal ( jQuery . escapeSelector ( "\x80\x2D\x5F\xA9" ) , "\x80\x2D\x5F\xA9" ,
"Doesn't escape general punctuation or non-ASCII ISO-8859-1 characters" ) ;
assert . equal (
jQuery . escapeSelector ( "\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90" +
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" ) ,
"\\7f \x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90" +
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" ,
"Escapes DEL control character"
) ;
assert . equal ( jQuery . escapeSelector ( "\xA0\xA1\xA2" ) , "\xA0\xA1\xA2" ,
"Doesn't escape non-ASCII ISO-8859-1 characters" ) ;
assert . equal ( jQuery . escapeSelector ( "a0123456789b" ) , "a0123456789b" ,
"Doesn't escape embedded numbers" ) ;
assert . equal ( jQuery . escapeSelector ( "abcdefghijklmnopqrstuvwxyz" ) , "abcdefghijklmnopqrstuvwxyz" ,
"Doesn't escape lowercase ASCII letters" ) ;
assert . equal ( jQuery . escapeSelector ( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) , "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ,
"Doesn't escape uppercase ASCII letters" ) ;
assert . equal ( jQuery . escapeSelector ( "\x20\x21\x78\x79" ) , "\\ \\!xy" ,
"Escapes non-word ASCII characters" ) ;
// Astral symbol (U+1D306 TETRAGRAM FOR CENTRE)
assert . equal ( jQuery . escapeSelector ( "\uD834\uDF06" ) , "\uD834\uDF06" ,
"Doesn't escape astral characters" ) ;
// Lone surrogates
assert . equal ( jQuery . escapeSelector ( "\uDF06" ) , "\uDF06" , "Doesn't escape lone low surrogate" ) ;
assert . equal ( jQuery . escapeSelector ( "\uD834" ) , "\uD834" , "Doesn't escape lone high surrogate" ) ;
2016-01-27 17:57:04 +00:00
} ) ;
2022-10-11 09:55:46 +00:00
2022-11-21 22:23:39 +00:00
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "custom pseudos" , function ( assert ) {
2022-10-11 09:55:46 +00:00
assert . expect ( 6 ) ;
try {
jQuery . expr . filters . foundation = jQuery . expr . filters . root ;
assert . deepEqual ( jQuery . find ( ":foundation" ) , [ document . documentElement ] , "Copy element filter with new name" ) ;
} finally {
delete jQuery . expr . filters . foundation ;
}
try {
jQuery . expr . setFilters . primary = jQuery . expr . setFilters . first ;
assert . t ( "Copy set filter with new name" , "div#qunit-fixture :primary" , [ "firstp" ] ) ;
} finally {
delete jQuery . expr . setFilters . primary ;
}
try {
jQuery . expr . filters . aristotlean = jQuery . expr . createPseudo ( function ( ) {
return function ( elem ) {
return ! ! elem . id ;
} ;
} ) ;
assert . t ( "Custom element filter" , "#foo :aristotlean" , [ "sndp" , "en" , "yahoo" , "sap" , "anchor2" , "simon" ] ) ;
} finally {
delete jQuery . expr . filters . aristotlean ;
}
try {
jQuery . expr . filters . endswith = jQuery . expr . createPseudo ( function ( text ) {
return function ( elem ) {
return jQuery . text ( elem ) . slice ( - text . length ) === text ;
} ;
} ) ;
assert . t ( "Custom element filter with argument" , "a:endswith(ogle)" , [ "google" ] ) ;
} finally {
delete jQuery . expr . filters . endswith ;
}
try {
jQuery . expr . setFilters . second = jQuery . expr . createPseudo ( function ( ) {
return jQuery . expr . createPseudo ( function ( seed , matches ) {
if ( seed [ 1 ] ) {
matches [ 1 ] = seed [ 1 ] ;
seed [ 1 ] = false ;
}
} ) ;
} ) ;
assert . t ( "Custom set filter" , "#qunit-fixture p:second" , [ "ap" ] ) ;
} finally {
delete jQuery . expr . filters . second ;
}
try {
jQuery . expr . setFilters . slice = jQuery . expr . createPseudo ( function ( argument ) {
var bounds = argument . split ( ":" ) ;
return jQuery . expr . createPseudo ( function ( seed , matches ) {
var i = bounds [ 1 ] ;
// Match elements found at the specified indexes
while ( -- i >= bounds [ 0 ] ) {
if ( seed [ i ] ) {
matches [ i ] = seed [ i ] ;
seed [ i ] = false ;
}
}
} ) ;
} ) ;
assert . t ( "Custom set filter with argument" , "#qunit-fixture p:slice(1:3)" , [ "ap" , "sndp" ] ) ;
} finally {
delete jQuery . expr . filters . slice ;
}
} ) ;
2023-06-12 20:58:55 +00:00
QUnit . test ( "jQuery.find.matchesSelector" , function ( assert ) {
assert . expect ( 15 ) ;
var link = document . getElementById ( "simon1" ) ,
input = document . getElementById ( "text1" ) ,
option = document . getElementById ( "option1a" ) ,
disconnected = document . createElement ( "div" ) ;
link . title = "Don't click me" ;
assert . ok ( jQuery . find . matchesSelector ( link , "[rel='bookmark']" ) , "attribute-equals string" ) ;
assert . ok ( jQuery . find . matchesSelector ( link , "[rel=bookmark]" ) , "attribute-equals identifier" ) ;
assert . ok ( jQuery . find . matchesSelector ( link , "[\nrel = bookmark\t]" ) ,
"attribute-equals identifier (whitespace ignored)" ) ;
assert . ok ( jQuery . find . matchesSelector ( link , "a[title=\"Don't click me\"]" ) ,
"attribute-equals string containing single quote" ) ;
// trac-12303
input . setAttribute ( "data-pos" , ":first" ) ;
assert . ok ( jQuery . find . matchesSelector ( input , "input[data-pos=\\:first]" ) ,
"attribute-equals POS in identifier" ) ;
assert . ok ( jQuery . find . matchesSelector ( input , "input[data-pos=':first']" ) ,
"attribute-equals POS in string" ) ;
if ( QUnit . jQuerySelectors ) {
assert . ok ( jQuery . find . matchesSelector ( input , ":input[data-pos=':first']" ) ,
"attribute-equals POS in string after pseudo" ) ;
} else {
assert . ok ( "skip" , ":input not supported in selector-native" ) ;
}
option . setAttribute ( "test" , "" ) ;
assert . ok ( jQuery . find . matchesSelector ( option , "[id=option1a]" ) ,
"id attribute-equals identifier" ) ;
if ( QUnit . jQuerySelectors ) {
assert . ok ( jQuery . find . matchesSelector ( option , "[id*=option1][type!=checkbox]" ) ,
"attribute-not-equals identifier" ) ;
} else {
assert . ok ( "skip" , "[key!=value] not supported in selector-native" ) ;
}
assert . ok ( jQuery . find . matchesSelector ( option , "[id*=option1]" ) , "attribute-contains identifier" ) ;
assert . ok ( ! jQuery . find . matchesSelector ( option , "[test^='']" ) ,
"attribute-starts-with empty string (negative)" ) ;
option . className = "=]" ;
assert . ok ( jQuery . find . matchesSelector ( option , ".\\=\\]" ) ,
"class selector with attribute-equals confusable" ) ;
assert . ok ( jQuery . find . matchesSelector ( disconnected , "div" ) , "disconnected element" ) ;
assert . ok ( jQuery . find . matchesSelector ( link , "* > *" ) , "child combinator matches in document" ) ;
assert . ok ( ! jQuery . find . matchesSelector ( disconnected , "* > *" ) , "child combinator fails in fragment" ) ;
} ) ;
QUnit . test ( "jQuery.find.matches" , function ( assert ) {
assert . expect ( 4 ) ;
var iframeChild ,
input = document . getElementById ( "text1" ) ,
div = document . createElement ( "div" ) ,
iframe = document . getElementById ( "iframe" ) ,
iframeDoc = iframe . contentDocument || iframe . contentWindow . document ;
assert . deepEqual ( jQuery . find . matches ( "input" , [ input ] ) , [ input ] ,
"jQuery.find.matches with seed of input element" ) ;
assert . deepEqual ( jQuery . find . matches ( "div" , [ div ] ) , [ div ] ,
"jQuery.find.matches with disconnected element" ) ;
iframeDoc . open ( ) ;
iframeDoc . write ( "<body><div id='foo'><div id='bar'></div></div></body>" ) ;
iframeDoc . close ( ) ;
iframeChild = iframeDoc . getElementById ( "bar" ) ;
assert . deepEqual (
jQuery . find . matches ( ":root > body > #foo > #bar" , [ iframeChild ] ) ,
[ iframeChild ] ,
"jQuery.find.matches infers context from element"
) ;
assert . deepEqual (
jQuery . find . matches ( ":root *" , [ div , iframeChild , input ] ) ,
[ iframeChild , input ] ,
"jQuery.find.matches infers context from each seed element"
) ;
} ) ;
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "jQuery.find.select with pre-compiled function" , function ( assert ) {
assert . expect ( 6 ) ;
supportjQuery . each ( [
"#qunit-fixture #first" ,
"ol#listWithTabIndex > li[tabindex]" ,
"#liveSpan1"
] , function ( i , selector ) {
var compiled = jQuery . find . compile ( selector ) ;
assert . equal ( jQuery . find . select ( compiled , document ) . length ,
1 , "Should match using a compiled selector function" ) ;
assert . equal (
jQuery . find . select ( compiled , jQuery ( "#first" ) [ 0 ] ) . length ,
0 , "Should not match with different context" ) ;
} ) ;
} ) ;
// Internal, but we test it for backwards compatibility for edge cases
QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "jQuery.find.tokenize" , function ( assert ) {
assert . expect ( 1 ) ;
var selector = "#id .class > div[prop=\"value\"] + input:nth-child(1):button, span:contains(\"Text\") ~ div:has(div:has(span)):not(.not-this.not-that > div)" ,
tokens = [
[
{
"value" : "#id" ,
"type" : "ID" ,
"matches" : [
"id"
]
} ,
{
"value" : " " ,
"type" : " "
} ,
{
"value" : ".class" ,
"type" : "CLASS" ,
"matches" : [
"class"
]
} ,
{
"value" : " > " ,
"type" : ">"
} ,
{
"value" : "div" ,
"type" : "TAG" ,
"matches" : [
"div"
]
} ,
{
"value" : "[prop=\"value\"]" ,
"type" : "ATTR" ,
"matches" : [
"prop" ,
"=" ,
"value"
]
} ,
{
"value" : " + " ,
"type" : "+"
} ,
{
"value" : "input" ,
"type" : "TAG" ,
"matches" : [
"input"
]
} ,
{
"value" : ":nth-child(1)" ,
"type" : "CHILD" ,
"matches" : [
"nth" ,
"child" ,
"1" ,
0 ,
1 ,
undefined ,
"" ,
"1"
]
} ,
{
"value" : ":button" ,
"type" : "PSEUDO" ,
"matches" : [
"button" ,
undefined
]
}
] ,
[
{
"value" : "span" ,
"type" : "TAG" ,
"matches" : [
"span"
]
} ,
{
"value" : ":contains(\"Text\")" ,
"type" : "PSEUDO" ,
"matches" : [
"contains" ,
"Text"
]
} ,
{
"value" : " ~ " ,
"type" : "~"
} ,
{
"value" : "div" ,
"type" : "TAG" ,
"matches" : [
"div"
]
} ,
{
"value" : ":has(div:has(span))" ,
"type" : "PSEUDO" ,
"matches" : [
"has" ,
"div:has(span)"
]
} ,
{
"value" : ":not(.not-this.not-that > div)" ,
"type" : "PSEUDO" ,
"matches" : [
"not" ,
".not-this.not-that > div"
]
}
]
] ;
assert . deepEqual ( jQuery . find . tokenize ( selector ) , tokens , "Tokenization successful" ) ;
} ) ;