Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow specifying preferred attributes #7

Merged
merged 2 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]' );
} );
});
Comment on lines -110 to +146
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only change here was nesting under a new describe block


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
Loading