define( [ "jquery", "ui/data", "ui/escape-selector", "ui/focusable", "ui/tabbable" ], function( $ ) { module( "core - selectors" ); function isFocusable( selector, msg ) { QUnit.push( $( selector ).is( ":focusable" ), null, null, msg + " - selector " + selector + " is focusable" ); } function isNotFocusable( selector, msg ) { QUnit.push( $( selector ).length && !$( selector ).is( ":focusable" ), null, null, msg + " - selector " + selector + " is not focusable" ); } function isTabbable( selector, msg ) { QUnit.push( $( selector ).is( ":tabbable" ), null, null, msg + " - selector " + selector + " is tabbable" ); } function isNotTabbable( selector, msg ) { QUnit.push( $( selector ).length && !$( selector ).is( ":tabbable" ), null, null, msg + " - selector " + selector + " is not tabbable" ); } test( "data", function() { expect( 15 ); var element; function shouldHaveData( msg ) { ok( element.is( ":data(test)" ), msg ); } function shouldNotHaveData( msg ) { ok( !element.is( ":data(test)" ), msg ); } element = $( "
" ); shouldNotHaveData( "data never set" ); element = $( "
" ).data( "test", null ); shouldNotHaveData( "data is null" ); element = $( "
" ).data( "test", true ); shouldHaveData( "data set to true" ); element = $( "
" ).data( "test", false ); shouldNotHaveData( "data set to false" ); element = $( "
" ).data( "test", 0 ); shouldNotHaveData( "data set to 0" ); element = $( "
" ).data( "test", 1 ); shouldHaveData( "data set to 1" ); element = $( "
" ).data( "test", "" ); shouldNotHaveData( "data set to empty string" ); element = $( "
" ).data( "test", "foo" ); shouldHaveData( "data set to string" ); element = $( "
" ).data( "test", [] ); shouldHaveData( "data set to empty array" ); element = $( "
" ).data( "test", [ 1 ] ); shouldHaveData( "data set to array" ); element = $( "
" ).data( "test", {} ); shouldHaveData( "data set to empty object" ); element = $( "
" ).data( "test", { foo: "bar" } ); shouldHaveData( "data set to object" ); element = $( "
" ).data( "test", new Date() ); shouldHaveData( "data set to date" ); element = $( "
" ).data( "test", /test/ ); shouldHaveData( "data set to regexp" ); element = $( "
" ).data( "test", function() {} ); shouldHaveData( "data set to function" ); } ); test( "focusable - visible, enabled elements", function() { expect( 20 ); isNotFocusable( "#formNoTabindex", "form" ); isFocusable( "#formTabindex", "form with tabindex" ); isFocusable( "#visibleAncestor-inputTypeNone", "input, no type" ); isFocusable( "#visibleAncestor-inputTypeText", "input, type text" ); isFocusable( "#visibleAncestor-inputTypeCheckbox", "input, type checkbox" ); isFocusable( "#visibleAncestor-inputTypeRadio", "input, type radio" ); isFocusable( "#visibleAncestor-inputTypeButton", "input, type button" ); isNotFocusable( "#visibleAncestor-inputTypeHidden", "input, type hidden" ); isFocusable( "#visibleAncestor-button", "button" ); isFocusable( "#visibleAncestor-select", "select" ); isFocusable( "#visibleAncestor-textarea", "textarea" ); isFocusable( "#visibleAncestor-object", "object" ); isFocusable( "#visibleAncestor-anchorWithHref", "anchor with href" ); isNotFocusable( "#visibleAncestor-anchorWithoutHref", "anchor without href" ); isNotFocusable( "#visibleAncestor-span", "span" ); isNotFocusable( "#visibleAncestor-div", "div" ); isFocusable( "#visibleAncestor-spanWithTabindex", "span with tabindex" ); isFocusable( "#visibleAncestor-divWithNegativeTabindex", "div with tabindex" ); isFocusable( "#nestedVisibilityInheritWithVisibleAncestor", "span, visibility: inherit inside visibility: visible parent" ); isFocusable( "#nestedVisibilityInheritWithVisibleAncestor-input", "input, visibility: inherit inside visibility: visible parent" ); } ); test( "focusable - disabled elements", function() { expect( 9 ); isNotFocusable( "#disabledElement-inputTypeNone", "input, no type" ); isNotFocusable( "#disabledElement-inputTypeText", "input, type text" ); isNotFocusable( "#disabledElement-inputTypeCheckbox", "input, type checkbox" ); isNotFocusable( "#disabledElement-inputTypeRadio", "input, type radio" ); isNotFocusable( "#disabledElement-inputTypeButton", "input, type button" ); isNotFocusable( "#disabledElement-inputTypeHidden", "input, type hidden" ); isNotFocusable( "#disabledElement-button", "button" ); isNotFocusable( "#disabledElement-select", "select" ); isNotFocusable( "#disabledElement-textarea", "textarea" ); } ); test( "focusable - hidden styles", function() { expect( 12 ); isNotFocusable( "#displayNoneAncestor-input", "input, display: none parent" ); isNotFocusable( "#displayNoneAncestor-span", "span with tabindex, display: none parent" ); isNotFocusable( "#visibilityHiddenAncestor-input", "input, visibility: hidden parent" ); isNotFocusable( "#visibilityHiddenAncestor-span", "span with tabindex, visibility: hidden parent" ); isFocusable( "#nestedVisibilityOverrideAncestor-input", "input, visibility: visible parent but visibility: hidden grandparent" ); isFocusable( "#nestedVisibilityOverrideAncestor-span", "span with tabindex, visibility: visible parent but visibility: hidden grandparent " ); isNotFocusable( "#nestedVisibilityInheritWithHiddenAncestor", "span, visibility: inherit inside visibility: hidden parent" ); isNotFocusable( "#nestedVisibilityInheritWithHiddenAncestor-input", "input, visibility: inherit inside visibility: hidden parent" ); isNotFocusable( "#displayNone-input", "input, display: none" ); isNotFocusable( "#visibilityHidden-input", "input, visibility: hidden" ); isNotFocusable( "#displayNone-span", "span with tabindex, display: none" ); isNotFocusable( "#visibilityHidden-span", "span with tabindex, visibility: hidden" ); } ); test( "focusable - natively focusable with various tabindex", function() { expect( 4 ); isFocusable( "#inputTabindex0", "input, tabindex 0" ); isFocusable( "#inputTabindex10", "input, tabindex 10" ); isFocusable( "#inputTabindex-1", "input, tabindex -1" ); isFocusable( "#inputTabindex-50", "input, tabindex -50" ); } ); test( "focusable - not natively focusable with various tabindex", function() { expect( 4 ); isFocusable( "#spanTabindex0", "span, tabindex 0" ); isFocusable( "#spanTabindex10", "span, tabindex 10" ); isFocusable( "#spanTabindex-1", "span, tabindex -1" ); isFocusable( "#spanTabindex-50", "span, tabindex -50" ); } ); test( "focusable - area elements", function() { expect( 3 ); isFocusable( "#areaCoordsHref", "coords and href" ); isFocusable( "#areaNoCoordsHref", "href but no coords" ); isNotFocusable( "#areaNoImg", "not associated with an image" ); } ); test( "focusable - dimensionless parent with overflow", function() { expect( 1 ); isFocusable( "#dimensionlessParent", "input" ); } ); test( "tabbable - visible, enabled elements", function() { expect( 18 ); isNotTabbable( "#formNoTabindex", "form" ); isTabbable( "#formTabindex", "form with tabindex" ); isTabbable( "#visibleAncestor-inputTypeNone", "input, no type" ); isTabbable( "#visibleAncestor-inputTypeText", "input, type text" ); isTabbable( "#visibleAncestor-inputTypeCheckbox", "input, type checkbox" ); isTabbable( "#visibleAncestor-inputTypeRadio", "input, type radio" ); isTabbable( "#visibleAncestor-inputTypeButton", "input, type button" ); isNotTabbable( "#visibleAncestor-inputTypeHidden", "input, type hidden" ); isTabbable( "#visibleAncestor-button", "button" ); isTabbable( "#visibleAncestor-select", "select" ); isTabbable( "#visibleAncestor-textarea", "textarea" ); isTabbable( "#visibleAncestor-object", "object" ); isTabbable( "#visibleAncestor-anchorWithHref", "anchor with href" ); isNotTabbable( "#visibleAncestor-anchorWithoutHref", "anchor without href" ); isNotTabbable( "#visibleAncestor-span", "span" ); isNotTabbable( "#visibleAncestor-div", "div" ); isTabbable( "#visibleAncestor-spanWithTabindex", "span with tabindex" ); isNotTabbable( "#visibleAncestor-divWithNegativeTabindex", "div with tabindex" ); } ); test( "tabbable - disabled elements", function() { expect( 9 ); isNotTabbable( "#disabledElement-inputTypeNone", "input, no type" ); isNotTabbable( "#disabledElement-inputTypeText", "input, type text" ); isNotTabbable( "#disabledElement-inputTypeCheckbox", "input, type checkbox" ); isNotTabbable( "#disabledElement-inputTypeRadio", "input, type radio" ); isNotTabbable( "#disabledElement-inputTypeButton", "input, type button" ); isNotTabbable( "#disabledElement-inputTypeHidden", "input, type hidden" ); isNotTabbable( "#disabledElement-button", "button" ); isNotTabbable( "#disabledElement-select", "select" ); isNotTabbable( "#disabledElement-textarea", "textarea" ); } ); test( "tabbable - hidden styles", function() { expect( 10 ); isNotTabbable( "#displayNoneAncestor-input", "input, display: none parent" ); isNotTabbable( "#displayNoneAncestor-span", "span with tabindex, display: none parent" ); isNotTabbable( "#visibilityHiddenAncestor-input", "input, visibility: hidden parent" ); isNotTabbable( "#visibilityHiddenAncestor-span", "span with tabindex, visibility: hidden parent" ); isTabbable( "#nestedVisibilityOverrideAncestor-input", "input, visibility: visible parent but visibility: hidden grandparent" ); isTabbable( "#nestedVisibilityOverrideAncestor-span", "span with tabindex, visibility: visible parent but visibility: hidden grandparent " ); isNotTabbable( "#displayNone-input", "input, display: none" ); isNotTabbable( "#visibilityHidden-input", "input, visibility: hidden" ); isNotTabbable( "#displayNone-span", "span with tabindex, display: none" ); isNotTabbable( "#visibilityHidden-span", "span with tabindex, visibility: hidden" ); } ); test( "tabbable - natively tabbable with various tabindex", function() { expect( 4 ); isTabbable( "#inputTabindex0", "input, tabindex 0" ); isTabbable( "#inputTabindex10", "input, tabindex 10" ); isNotTabbable( "#inputTabindex-1", "input, tabindex -1" ); isNotTabbable( "#inputTabindex-50", "input, tabindex -50" ); } ); test( "tabbable - not natively tabbable with various tabindex", function() { expect( 4 ); isTabbable( "#spanTabindex0", "span, tabindex 0" ); isTabbable( "#spanTabindex10", "span, tabindex 10" ); isNotTabbable( "#spanTabindex-1", "span, tabindex -1" ); isNotTabbable( "#spanTabindex-50", "span, tabindex -50" ); } ); test( "tabbable - area elements", function() { expect( 3 ); isTabbable( "#areaCoordsHref", "coords and href" ); isTabbable( "#areaNoCoordsHref", "href but no coords" ); isNotTabbable( "#areaNoImg", "not associated with an image" ); } ); test( "tabbable - dimensionless parent with overflow", function() { expect( 1 ); isTabbable( "#dimensionlessParent", "input" ); } ); test( "escapeSelector", function() { expect( 1 ); equal( $( "#" + $.ui.escapeSelector( "weird-['x']-id" ) ).length, 1, "properly escapes selectors to use as an id" ); } ); } );