@cypress/unique-selector 0.4.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/lib/getData.js +7 -23
  2. package/lib/getName.js +19 -0
  3. package/lib/index.js +34 -56
  4. package/lib/isUnique.js +6 -2
  5. package/package.json +8 -11
  6. package/.babelrc +0 -3
  7. package/.eslintrc +0 -42
  8. package/.history/package-lock_20211116100405.json +0 -7884
  9. package/.history/package-lock_20211116101347.json +0 -7884
  10. package/.history/package_20180226102655.json +0 -62
  11. package/.history/package_20211018091805.json +0 -62
  12. package/.history/package_20211018091928.json +0 -62
  13. package/.history/package_20211116101343.json +0 -62
  14. package/.history/src/getData_20211116100405.js +0 -24
  15. package/.history/src/getData_20211116100500.js +0 -24
  16. package/.history/src/getData_20211116100511.js +0 -24
  17. package/.history/src/getData_20211116100803.js +0 -25
  18. package/.history/src/getData_20211116100925.js +0 -25
  19. package/.history/src/getData_20211116101054.js +0 -25
  20. package/.history/src/getData_20211116101058.js +0 -25
  21. package/.history/src/getData_20211116101234.js +0 -26
  22. package/.history/src/getData_20211116101243.js +0 -28
  23. package/.history/src/getData_20211116101301.js +0 -29
  24. package/.history/test/unique-selector_20180226102601.js +0 -131
  25. package/.history/test/unique-selector_20211018092001.js +0 -131
  26. package/.history/test/unique-selector_20211018092018.js +0 -131
  27. package/.history/test/unique-selector_20211018092209.js +0 -132
  28. package/.history/test/unique-selector_20211018092230.js +0 -132
  29. package/.history/test/unique-selector_20211018092245.js +0 -130
  30. package/.travis.yml +0 -11
  31. package/component.json +0 -12
  32. package/src/getAttributes.js +0 -20
  33. package/src/getClasses.js +0 -38
  34. package/src/getCombinations.js +0 -44
  35. package/src/getData.js +0 -29
  36. package/src/getID.js +0 -17
  37. package/src/getNthChild.js +0 -33
  38. package/src/getParents.js +0 -19
  39. package/src/getTag.js +0 -9
  40. package/src/index.js +0 -197
  41. package/src/isElement.js +0 -17
  42. package/src/isUnique.js +0 -12
  43. package/static/bundle.js +0 -5
  44. package/test/index.html +0 -0
  45. package/test/unique-selector.js +0 -146
package/component.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "name": "unique-selector",
3
- "repo": "ericclemmons/unique-selector",
4
- "description": "Given a DOM element, return a unique CSS selector matching only that element",
5
- "version": "0.0.1",
6
- "keywords": ["element", "css", "selector"],
7
- "development": {
8
- "visionmedia/mocha-cloud": "*"
9
- },
10
- "license": "MIT",
11
- "scripts": ["index.js"]
12
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Returns the Attribute selectors of the element
3
- * @param { DOM Element } element
4
- * @param { Array } array of attributes to ignore
5
- * @return { Array }
6
- */
7
- export function getAttributes( el, attributesToIgnore = ['id', 'class', 'length'] )
8
- {
9
- const { attributes } = el;
10
- const attrs = [ ...attributes ];
11
-
12
- return attrs.reduce( ( sum, next ) =>
13
- {
14
- if ( ! ( attributesToIgnore.indexOf( next.nodeName ) > -1 ) )
15
- {
16
- sum.push( `[${next.nodeName}="${next.value}"]` );
17
- }
18
- return sum;
19
- }, [] );
20
- }
package/src/getClasses.js DELETED
@@ -1,38 +0,0 @@
1
- import 'css.escape';
2
-
3
- /**
4
- * Get class names for an element
5
- *
6
- * @pararm { Element } el
7
- * @return { Array }
8
- */
9
- export function getClasses( el )
10
- {
11
- if( !el.hasAttribute( 'class' ) )
12
- {
13
- return [];
14
- }
15
-
16
- try {
17
- return Array.prototype.slice.call( el.classList );
18
- } catch (e) {
19
- let className = el.getAttribute( 'class' );
20
-
21
- // remove duplicate and leading/trailing whitespaces
22
- className = className.trim().replace( /\s+/g, ' ' );
23
-
24
- // split into separate classnames
25
- return className.split( ' ' );
26
- }
27
- }
28
-
29
- /**
30
- * Returns the Class selectors of the element
31
- * @param { Object } element
32
- * @return { Array }
33
- */
34
- export function getClassSelectors( el )
35
- {
36
- const classList = getClasses( el ).filter( Boolean );
37
- return classList.map( cl => `.${CSS.escape( cl )}` );
38
- }
@@ -1,44 +0,0 @@
1
- /**
2
- * Recursively combinate items.
3
- * @param { Array } result
4
- * @param { Array } items
5
- * @param { Array } data
6
- * @param { Number } start
7
- * @param { Number } end
8
- * @param { Number } index
9
- * @param { Number } k
10
- */
11
- function kCombinations( result, items, data, start, end, index, k )
12
- {
13
- if( index === k )
14
- {
15
- result.push( data.slice( 0, index ).join( '' ) );
16
- return;
17
- }
18
-
19
- for( let i = start; i <= end && end - i + 1 >= k - index; ++i )
20
- {
21
- data[index] = items[i];
22
- kCombinations( result, items, data, i + 1, end, index + 1, k );
23
- }
24
- }
25
-
26
- /**
27
- * Returns all the possible selector combinations
28
- * @param { Array } items
29
- * @param { Number } k
30
- * @return { Array }
31
- */
32
- export function getCombinations( items, k )
33
- {
34
- const result = [],
35
- n = items.length,
36
- data = [];
37
-
38
- for( var l = 1; l <= k; ++l )
39
- {
40
- kCombinations( result, items, data, 0, n - 1, 0, l );
41
- }
42
-
43
- return result;
44
- }
package/src/getData.js DELETED
@@ -1,29 +0,0 @@
1
- /**
2
- * Returns the data-{dataAttr} selector of the element
3
- * @param { String } selectorType - The type of selector to return.
4
- * @param { String } attributes - The attributes of the element.
5
- * @return { String | null } - The data-{dataAttr} selector of the element.
6
- */
7
-
8
- export const getData = ( selectorType, attributes ) =>
9
- {
10
- for ( let i = 0; i < attributes.length; i++ )
11
- {
12
- // extract node name + value
13
- const { nodeName, value } = attributes[ i ];
14
-
15
- // if this matches our selector
16
- if ( nodeName === selectorType )
17
- {
18
- if ( value )
19
- {
20
- // if we have value that needs quotes
21
- return `[${nodeName}="${value}"]`;
22
- }
23
-
24
- return `[${nodeName}]`;
25
- }
26
- }
27
-
28
- return null;
29
- };
package/src/getID.js DELETED
@@ -1,17 +0,0 @@
1
- import 'css.escape';
2
-
3
- /**
4
- * Returns the Tag of the element
5
- * @param { Object } element
6
- * @return { String }
7
- */
8
- export function getID( el )
9
- {
10
- const id = el.getAttribute( 'id' );
11
-
12
- if( id !== null && id !== '')
13
- {
14
- return `#${CSS.escape( id )}`;
15
- }
16
- return null;
17
- }
@@ -1,33 +0,0 @@
1
- import { isElement } from './isElement';
2
-
3
- /**
4
- * Returns the selectors based on the position of the element relative to its siblings
5
- * @param { Object } element
6
- * @return { Array }
7
- */
8
- export function getNthChild( element )
9
- {
10
- let counter = 0;
11
- let k;
12
- let sibling;
13
- const { parentNode } = element;
14
-
15
- if( Boolean( parentNode ) )
16
- {
17
- const { childNodes } = parentNode;
18
- const len = childNodes.length;
19
- for ( k = 0; k < len; k++ )
20
- {
21
- sibling = childNodes[ k ];
22
- if( isElement( sibling ) )
23
- {
24
- counter++;
25
- if( sibling === element )
26
- {
27
- return `:nth-child(${counter})`;
28
- }
29
- }
30
- }
31
- }
32
- return null;
33
- }
package/src/getParents.js DELETED
@@ -1,19 +0,0 @@
1
- import { isElement } from './isElement';
2
-
3
- /**
4
- * Returns all the element and all of its parents
5
- * @param { DOM Element }
6
- * @return { Array of DOM elements }
7
- */
8
- export function getParents( el )
9
- {
10
- const parents = [];
11
- let currentElement = el;
12
- while( isElement( currentElement ) )
13
- {
14
- parents.push( currentElement );
15
- currentElement = currentElement.parentNode;
16
- }
17
-
18
- return parents;
19
- }
package/src/getTag.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Returns the Tag of the element
3
- * @param { Object } element
4
- * @return { String }
5
- */
6
- export function getTag( el )
7
- {
8
- return el.tagName.toLowerCase().replace(/:/g, '\\:');
9
- }
package/src/index.js DELETED
@@ -1,197 +0,0 @@
1
- /**
2
- * Expose `unique`
3
- */
4
-
5
- import { getID } from './getID';
6
- import { getClassSelectors } from './getClasses';
7
- import { getCombinations } from './getCombinations';
8
- import { getAttributes } from './getAttributes';
9
- import { getNthChild } from './getNthChild';
10
- import { getTag } from './getTag';
11
- import { isUnique } from './isUnique';
12
- import { getParents } from './getParents';
13
- import { getData } from './getData';
14
-
15
- const dataRegex = /^data-(.+)/;
16
-
17
- /**
18
- * Returns all the selectors of the element
19
- * @param { Object } element
20
- * @return { Object }
21
- */
22
- function getAllSelectors( el, selectors, attributesToIgnore )
23
- {
24
- const funcs =
25
- {
26
- 'tag' : getTag,
27
- 'nth-child' : getNthChild,
28
- 'attributes' : elem => getAttributes( elem, attributesToIgnore ),
29
- 'class' : getClassSelectors,
30
- 'id' : getID,
31
- };
32
-
33
- return selectors
34
- .filter( ( selector ) => !dataRegex.test( selector ) )
35
- .reduce( ( res, next ) =>
36
- {
37
- res[ next ] = funcs[ next ]( el );
38
- return res;
39
- }, {} );
40
- }
41
-
42
- /**
43
- * Tests uniqueNess of the element inside its parent
44
- * @param { Object } element
45
- * @param { String } Selectors
46
- * @return { Boolean }
47
- */
48
- function testUniqueness( element, selector )
49
- {
50
- const { parentNode } = element;
51
- const elements = parentNode.querySelectorAll( selector );
52
- return elements.length === 1 && elements[ 0 ] === element;
53
- }
54
-
55
- /**
56
- * Tests all selectors for uniqueness and returns the first unique selector.
57
- * @param { Object } element
58
- * @param { Array } selectors
59
- * @return { String }
60
- */
61
- function getFirstUnique( element, selectors )
62
- {
63
- return selectors.find( testUniqueness.bind( null, element ) );
64
- }
65
-
66
- /**
67
- * Checks all the possible selectors of an element to find one unique and return it
68
- * @param { Object } element
69
- * @param { Array } items
70
- * @param { String } tag
71
- * @return { String }
72
- */
73
- function getUniqueCombination( element, items, tag )
74
- {
75
- let combinations = getCombinations( items, 3 ),
76
- firstUnique = getFirstUnique( element, combinations );
77
-
78
- if( Boolean( firstUnique ) )
79
- {
80
- return firstUnique;
81
- }
82
-
83
- if( Boolean( tag ) )
84
- {
85
- combinations = combinations.map( combination => tag + combination );
86
- firstUnique = getFirstUnique( element, combinations );
87
-
88
- if( Boolean( firstUnique ) )
89
- {
90
- return firstUnique;
91
- }
92
- }
93
-
94
- return null;
95
- }
96
-
97
- /**
98
- * Returns a uniqueSelector based on the passed options
99
- * @param { DOM } element
100
- * @param { Array } options
101
- * @return { String }
102
- */
103
- function getUniqueSelector( element, selectorTypes, attributesToIgnore )
104
- {
105
- let foundSelector;
106
-
107
- const attributes = [...element.attributes];
108
-
109
- const elementSelectors = getAllSelectors( element, selectorTypes, attributesToIgnore );
110
-
111
- for( let selectorType of selectorTypes )
112
- {
113
- let selector = elementSelectors[ selectorType ];
114
-
115
- // if we are a data attribute
116
- if ( dataRegex.test( selectorType ) )
117
- {
118
- const dataSelector = getData( selectorType, attributes );
119
-
120
- // if we found a selector via data attributes
121
- if ( dataSelector )
122
- {
123
- selector = dataSelector;
124
- selectorType = 'data';
125
- }
126
- }
127
-
128
- if ( !Boolean( selector ) ) continue;
129
-
130
- switch ( selectorType )
131
- {
132
- case 'data' :
133
- case 'id' :
134
- case 'tag':
135
- if ( testUniqueness( element, selector ) )
136
- {
137
- return selector;
138
- }
139
- break;
140
- case 'class':
141
- case 'attributes':
142
- if ( selector.length )
143
- {
144
- foundSelector = getUniqueCombination( element, selector, elementSelectors.tag );
145
- if ( foundSelector )
146
- {
147
- return foundSelector;
148
- }
149
- }
150
- break;
151
-
152
- case 'nth-child':
153
- return selector;
154
-
155
- default:
156
- break;
157
- }
158
- }
159
- return '*';
160
- }
161
-
162
- /**
163
- * Generate unique CSS selector for given DOM element
164
- *
165
- * @param {Element} el
166
- * @return {String}
167
- * @api private
168
- */
169
-
170
- export default function unique( el, options={} )
171
- {
172
- const { selectorTypes=['id', 'class', 'tag', 'nth-child'], attributesToIgnore= ['id', 'class', 'length'] } = options;
173
- const allSelectors = [];
174
- const parents = getParents( el );
175
-
176
- for( let elem of parents )
177
- {
178
- const selector = getUniqueSelector( elem, selectorTypes, attributesToIgnore );
179
- if( Boolean( selector ) )
180
- {
181
- allSelectors.push( selector );
182
- }
183
- }
184
-
185
- const selectors = [];
186
- for( let it of allSelectors )
187
- {
188
- selectors.unshift( it );
189
- const selector = selectors.join( ' > ' );
190
- if( isUnique( el, selector ) )
191
- {
192
- return selector;
193
- }
194
- }
195
-
196
- return null;
197
- }
package/src/isElement.js DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * Determines if the passed el is a DOM element
3
- */
4
- export function isElement( el )
5
- {
6
- let isElem;
7
-
8
- if ( typeof HTMLElement === 'object' )
9
- {
10
- isElem = el instanceof HTMLElement;
11
- }
12
- else
13
- {
14
- isElem = !!el && ( typeof el === 'object' ) && el.nodeType === 1 && typeof el.nodeName === 'string';
15
- }
16
- return isElem;
17
- }
package/src/isUnique.js DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * Checks if the selector is unique
3
- * @param { Object } element
4
- * @param { String } selector
5
- * @return { Array }
6
- */
7
- export function isUnique( el, selector )
8
- {
9
- if( !Boolean( selector ) ) return false;
10
- const elems = el.ownerDocument.querySelectorAll( selector );
11
- return elems.length === 1 && elems[ 0 ] === el;
12
- }