Skip to content

Commit

Permalink
feat: Allow specifying preferred attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-plummer committed Feb 5, 2024
1 parent cdf1116 commit 84c7a7b
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/getData.js → src/getAttribute.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Returns the data-{dataAttr} selector of the element
* @param { String } selectorType - The type of selector to return.
* Returns the {attr} selector of the element
* @param { String } selectorType - The attribute selector to return.
* @param { String } attributes - The attributes of the element.
* @return { String | null } - The data-{dataAttr} selector of the element.
* @return { String | null } - The {attr} selector of the element.
*/

export const getData = ( selectorType, attributes ) =>
export const getAttribute = ( selectorType, attributes ) =>
{
for ( let i = 0; i < attributes.length; i++ )
{
Expand Down
24 changes: 14 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { getNthChild } from './getNthChild';
import { getTag } from './getTag';
import { isUnique } from './isUnique';
import { getParents } from './getParents';
import { getData } from './getData';
import { getAttribute } from './getAttribute';

const dataRegex = /^data-(.+)/;
const dataRegex = /^data-.+/;
const attrRegex = /^attribute-(.+)/m;

/**
* Returns all the selectors of the element
Expand All @@ -33,7 +34,7 @@ function getAllSelectors( el, selectors, attributesToIgnore )
};

return selectors
.filter( ( selector ) => !dataRegex.test( selector ) )
.filter( ( selector ) => !dataRegex.test( selector ) && !attrRegex.test( selector ) )
.reduce( ( res, next ) =>
{
res[ next ] = funcs[ next ]( el );
Expand Down Expand Up @@ -119,23 +120,26 @@ function getUniqueSelector( element, selectorTypes, attributesToIgnore )
let selector = elementSelectors[ selectorType ];

// if we are a data attribute
if ( dataRegex.test( selectorType ) )
const isDataAttributeSelectorType = dataRegex.test(selectorType)
const isAttributeSelectorType = !isDataAttributeSelectorType && attrRegex.test(selectorType)
if ( isDataAttributeSelectorType || isAttributeSelectorType )
{
const dataSelector = getData( selectorType, attributes );
const attributeToQuery = isDataAttributeSelectorType ? selectorType : selectorType.replace(attrRegex, '$1')
const attributeSelector = getAttribute( attributeToQuery, attributes );

// if we found a selector via data attributes
if ( dataSelector )
// if we found a selector via attribute
if ( attributeSelector )
{
selector = dataSelector;
selectorType = 'data';
selector = attributeSelector;
selectorType = 'attribute';
}
}

if ( !Boolean( selector ) ) continue;

switch ( selectorType )
{
case 'data' :
case 'attribute' :
case 'id' :
case 'name':
case 'tag':
Expand Down
85 changes: 53 additions & 32 deletions test/unique-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,41 +107,62 @@ describe( 'Unique Selector Tests', () =>
expect( uniqueSelector ).to.equal( '[test="5"]' );
} );

it( 'data-foo', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo="so" class="test6"></div>' );
const findNode = $( 'body' ).find( '.test6' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo'] } );
expect( uniqueSelector ).to.equal( '[data-foo="so"]' );
} );
describe('data attribute', () => {
it( 'data-foo', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo="so" class="test6"></div>' );
const findNode = $( 'body' ).find( '.test6' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo'] } );
expect( uniqueSelector ).to.equal( '[data-foo="so"]' );
} );

it( 'data-foo-bar-baz', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo-bar-baz="so" class="test6"></div>' );
const findNode = $( 'body' ).find( '.test6' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo-bar-baz'] } );
expect( uniqueSelector ).to.equal( '[data-foo-bar-baz="so"]' );
} );
it( 'data-foo-bar-baz', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo-bar-baz="so" class="test6"></div>' );
const findNode = $( 'body' ).find( '.test6' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo-bar-baz'] } );
expect( uniqueSelector ).to.equal( '[data-foo-bar-baz="so"]' );
} );

it( 'data-foo-bar with quotes', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo-bar="button 123" class="test7"></div>' );
const findNode = $( 'body' ).find( '.test7' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo-bar'] } );
expect( uniqueSelector ).to.equal( '[data-foo-bar="button 123"]' );
} );
it( 'data-foo-bar with quotes', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo-bar="button 123" class="test7"></div>' );
const findNode = $( 'body' ).find( '.test7' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo-bar'] } );
expect( uniqueSelector ).to.equal( '[data-foo-bar="button 123"]' );
} );

it( 'data-foo without value', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo class="test7"></div>' );
const findNode = $( 'body' ).find( '.test7' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo'] } );
expect( uniqueSelector ).to.equal( '[data-foo]' );
} );
it( 'data-foo without value', () =>
{
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div data-foo class="test7"></div>' );
const findNode = $( 'body' ).find( '.test7' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['data-foo'] } );
expect( uniqueSelector ).to.equal( '[data-foo]' );
} );
});

describe('standard attribute', () => {
it('attribute without value', () => {
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div contenteditable class="test8"></div>' );
const findNode = $( 'body' ).find( '.test8' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['attribute-contenteditable'] } );
expect( uniqueSelector ).to.equal( '[contenteditable]' );
})

it('attribute with value', () => {
$( 'body' ).get( 0 ).innerHTML = ''; // Clear previous appends
$( 'body' ).append( '<div role="button" class="test9"></div>' );
const findNode = $( 'body' ).find( '.test9' ).get( 0 );
const uniqueSelector = unique( findNode, { selectorTypes : ['attribute-role'] } );
expect( uniqueSelector ).to.equal( '[role="button"]' );
})
})


describe('name', () => {
beforeEach(() => {
Expand Down

0 comments on commit 84c7a7b

Please sign in to comment.