(function($) {
/* by Elijah Manor
* Filter results by html5 data attributes either at design-time
* ( HTML5 data-attr ) or at runtime ( internal jQuery data() )
*
* Usages
* $( "p:dataAttr(mytype)" ) // returns all p's with data mytype attr
* $( "p:dataAttr(my, ^=)" ) // returns all p's that start with data myty attr
* $( "p:dataAttr(type, $=)" ) // returns all p's that ends with data myty attr
* $( "p:dataAttr(yty, ~=)" ) // returns all p's that contains data myty attr
*/
$.expr[ ":" ].dataAttr = function( element, index, match, array ) {
var parameters = match[ 3 ].split( "," ),
attr = $.trim( parameters[0] ),
compare = $.trim( parameters[1] ) || "=",
data = $( element ).data(),
matches = false;
$.each( data, function( key, _ ) {
index = key.indexOf( attr );
if ( compare === "=" ) {
matches = key === attr;
} else if ( compare === "^=" ) {
matches = index === 0;
} else if ( compare === "$=" ) {
matches = ~index && index === ( key.length - attr.length );
} else if ( compare === "~=" ) {
matches = !!~index;
}
if ( matches ) { return false; }
});
return matches;
};
})(jQuery);
pavlov.specify.globalApi = true;
pavlov.specify( "jQuery :dataAttr Pseudo Selector", function() {
var $fixture = $( "#qunit-fixture" );
describe( "Design-time Checks", function() {
it( "should not match an element that doesn't have the data-attr", function() {
var $p = $( "p:dataAttr(bogus)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 0 );
});
it( "should match an element that has a data-attr", function() {
var $p = $( "p:dataAttr(mytype)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
assert( $p.index() ).isEqualTo( 6 );
});
it( "should match an element that starts with a data-attr", function() {
var $p = $( "p:dataAttr(my, ^=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 5 );
});
it( "should match an element that ends with a data-attr", function() {
var $p = $( "p:dataAttr(type, $=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
assert( $p.index() ).isEqualTo( 6 );
});
it( "should match an element that contains a data-attr", function() {
var $p = $( "p:dataAttr(type, ~=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 2 );
assert( $p.eq( 0 ).index() ).isEqualTo( 6 );
assert( $p.eq( 1 ).index() ).isEqualTo( 7 );
});
});
describe( "Run-time Checks", function() {
it( "should not match an element that doesn't have data key", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "" ),
$p = $( "p:dataAttr(runtype)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
});
it( "should match an element that has data key with value of empty string", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "" ),
$p = $( "p:dataAttr(runtype)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
});
it( "should match an element that has a data key with value of non-empty string", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
$p = $( "p:dataAttr(runtype)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
});
it( "should match an element with data key starts with", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
$p = $( "p:dataAttr(run, ^=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
assert( $p.index() ).isEqualTo( 1 );
});
it( "should match an element with data key ends with", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
$p = $( "p:dataAttr(ntype, $=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
assert( $p.index() ).isEqualTo( 1 );
});
it( "should match an element with data key contains", function() {
var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
$p = $( "p:dataAttr(unt, ~=)" );
assert( $p ).isDefined();
assert( $p.length ).isEqualTo( 1 );
assert( $p.index() ).isEqualTo( 1 );
});
});
});