@cypress/unique-selector 0.4.4 → 1.1.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.
- package/lib/{getData.js → getAttribute.js} +4 -4
- package/lib/getName.js +19 -0
- package/lib/index.js +48 -66
- package/lib/isUnique.js +6 -2
- package/package.json +3 -9
|
@@ -4,13 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
/**
|
|
7
|
-
* Returns the
|
|
8
|
-
* @param { String } selectorType - The
|
|
7
|
+
* Returns the {attr} selector of the element
|
|
8
|
+
* @param { String } selectorType - The attribute selector to return.
|
|
9
9
|
* @param { String } attributes - The attributes of the element.
|
|
10
|
-
* @return { String | null } - The
|
|
10
|
+
* @return { String | null } - The {attr} selector of the element.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var getAttribute = exports.getAttribute = function getAttribute(selectorType, attributes) {
|
|
14
14
|
for (var i = 0; i < attributes.length; i++) {
|
|
15
15
|
// extract node name + value
|
|
16
16
|
var _attributes$i = attributes[i],
|
package/lib/getName.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getName = getName;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the `name` attribute of the element (if one exists)
|
|
9
|
+
* @param { Object } element
|
|
10
|
+
* @return { String }
|
|
11
|
+
*/
|
|
12
|
+
function getName(el) {
|
|
13
|
+
var name = el.getAttribute('name');
|
|
14
|
+
|
|
15
|
+
if (name !== null && name !== '') {
|
|
16
|
+
return '[name="' + name + '"]';
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,8 @@ var _getCombinations = require('./getCombinations');
|
|
|
13
13
|
|
|
14
14
|
var _getAttributes = require('./getAttributes');
|
|
15
15
|
|
|
16
|
+
var _getName = require('./getName');
|
|
17
|
+
|
|
16
18
|
var _getNthChild = require('./getNthChild');
|
|
17
19
|
|
|
18
20
|
var _getTag = require('./getTag');
|
|
@@ -21,13 +23,14 @@ var _isUnique = require('./isUnique');
|
|
|
21
23
|
|
|
22
24
|
var _getParents = require('./getParents');
|
|
23
25
|
|
|
24
|
-
var
|
|
26
|
+
var _getAttribute = require('./getAttribute');
|
|
25
27
|
|
|
26
28
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /**
|
|
27
29
|
* Expose `unique`
|
|
28
30
|
*/
|
|
29
31
|
|
|
30
|
-
var dataRegex = /^data
|
|
32
|
+
var dataRegex = /^data-.+/;
|
|
33
|
+
var attrRegex = /^attribute:(.+)/m;
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* Returns all the selectors of the element
|
|
@@ -42,11 +45,12 @@ function getAllSelectors(el, selectors, attributesToIgnore) {
|
|
|
42
45
|
return (0, _getAttributes.getAttributes)(elem, attributesToIgnore);
|
|
43
46
|
},
|
|
44
47
|
'class': _getClasses.getClassSelectors,
|
|
45
|
-
'id': _getID.getID
|
|
48
|
+
'id': _getID.getID,
|
|
49
|
+
'name': _getName.getName
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
return selectors.filter(function (selector) {
|
|
49
|
-
return !dataRegex.test(selector);
|
|
53
|
+
return !dataRegex.test(selector) && !attrRegex.test(selector);
|
|
50
54
|
}).reduce(function (res, next) {
|
|
51
55
|
res[next] = funcs[next](el);
|
|
52
56
|
return res;
|
|
@@ -62,8 +66,12 @@ function getAllSelectors(el, selectors, attributesToIgnore) {
|
|
|
62
66
|
function testUniqueness(element, selector) {
|
|
63
67
|
var parentNode = element.parentNode;
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
try {
|
|
70
|
+
var elements = parentNode.querySelectorAll(selector);
|
|
71
|
+
return elements.length === 1 && elements[0] === element;
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
/**
|
|
@@ -129,21 +137,25 @@ function getUniqueSelector(element, selectorTypes, attributesToIgnore) {
|
|
|
129
137
|
var selector = elementSelectors[selectorType];
|
|
130
138
|
|
|
131
139
|
// if we are a data attribute
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
var isDataAttributeSelectorType = dataRegex.test(selectorType);
|
|
141
|
+
var isAttributeSelectorType = !isDataAttributeSelectorType && attrRegex.test(selectorType);
|
|
142
|
+
if (isDataAttributeSelectorType || isAttributeSelectorType) {
|
|
143
|
+
var attributeToQuery = isDataAttributeSelectorType ? selectorType : selectorType.replace(attrRegex, '$1');
|
|
144
|
+
var attributeSelector = (0, _getAttribute.getAttribute)(attributeToQuery, attributes);
|
|
145
|
+
|
|
146
|
+
// if we found a selector via attribute
|
|
147
|
+
if (attributeSelector) {
|
|
148
|
+
selector = attributeSelector;
|
|
149
|
+
selectorType = 'attribute';
|
|
139
150
|
}
|
|
140
151
|
}
|
|
141
152
|
|
|
142
153
|
if (!Boolean(selector)) continue;
|
|
143
154
|
|
|
144
155
|
switch (selectorType) {
|
|
145
|
-
case '
|
|
156
|
+
case 'attribute':
|
|
146
157
|
case 'id':
|
|
158
|
+
case 'name':
|
|
147
159
|
case 'tag':
|
|
148
160
|
if (testUniqueness(element, selector)) {
|
|
149
161
|
return selector;
|
|
@@ -195,69 +207,39 @@ function getUniqueSelector(element, selectorTypes, attributesToIgnore) {
|
|
|
195
207
|
function unique(el) {
|
|
196
208
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
197
209
|
var _options$selectorType = options.selectorTypes,
|
|
198
|
-
selectorTypes = _options$selectorType === undefined ? ['id', 'class', 'tag', 'nth-child'] : _options$selectorType,
|
|
210
|
+
selectorTypes = _options$selectorType === undefined ? ['id', 'name', 'class', 'tag', 'nth-child'] : _options$selectorType,
|
|
199
211
|
_options$attributesTo = options.attributesToIgnore,
|
|
200
|
-
attributesToIgnore = _options$attributesTo === undefined ? ['id', 'class', 'length'] : _options$attributesTo
|
|
212
|
+
attributesToIgnore = _options$attributesTo === undefined ? ['id', 'class', 'length'] : _options$attributesTo,
|
|
213
|
+
selectorCache = options.selectorCache,
|
|
214
|
+
isUniqueCache = options.isUniqueCache;
|
|
201
215
|
|
|
202
216
|
var allSelectors = [];
|
|
203
|
-
var parents = (0, _getParents.getParents)(el);
|
|
204
|
-
|
|
205
|
-
var _iteratorNormalCompletion2 = true;
|
|
206
|
-
var _didIteratorError2 = false;
|
|
207
|
-
var _iteratorError2 = undefined;
|
|
208
217
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
var currentElement = el;
|
|
219
|
+
while (currentElement) {
|
|
220
|
+
var selector = selectorCache ? selectorCache.get(currentElement) : undefined;
|
|
212
221
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
} catch (err) {
|
|
219
|
-
_didIteratorError2 = true;
|
|
220
|
-
_iteratorError2 = err;
|
|
221
|
-
} finally {
|
|
222
|
-
try {
|
|
223
|
-
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
224
|
-
_iterator2.return();
|
|
225
|
-
}
|
|
226
|
-
} finally {
|
|
227
|
-
if (_didIteratorError2) {
|
|
228
|
-
throw _iteratorError2;
|
|
222
|
+
if (!selector) {
|
|
223
|
+
selector = getUniqueSelector(currentElement, selectorTypes, attributesToIgnore);
|
|
224
|
+
if (selectorCache) {
|
|
225
|
+
selectorCache.set(currentElement, selector);
|
|
229
226
|
}
|
|
230
227
|
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
var selectors = [];
|
|
234
|
-
var _iteratorNormalCompletion3 = true;
|
|
235
|
-
var _didIteratorError3 = false;
|
|
236
|
-
var _iteratorError3 = undefined;
|
|
237
228
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return _selector;
|
|
229
|
+
allSelectors.unshift(selector);
|
|
230
|
+
var maybeUniqueSelector = allSelectors.join(' > ');
|
|
231
|
+
var isUniqueSelector = isUniqueCache ? isUniqueCache.get(maybeUniqueSelector) : undefined;
|
|
232
|
+
if (isUniqueSelector === undefined) {
|
|
233
|
+
isUniqueSelector = (0, _isUnique.isUnique)(el, maybeUniqueSelector);
|
|
234
|
+
if (isUniqueCache) {
|
|
235
|
+
isUniqueCache.set(maybeUniqueSelector, isUniqueSelector);
|
|
246
236
|
}
|
|
247
237
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
} finally {
|
|
252
|
-
try {
|
|
253
|
-
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
|
254
|
-
_iterator3.return();
|
|
255
|
-
}
|
|
256
|
-
} finally {
|
|
257
|
-
if (_didIteratorError3) {
|
|
258
|
-
throw _iteratorError3;
|
|
259
|
-
}
|
|
238
|
+
|
|
239
|
+
if (isUniqueSelector) {
|
|
240
|
+
return maybeUniqueSelector;
|
|
260
241
|
}
|
|
242
|
+
currentElement = currentElement.parentNode;
|
|
261
243
|
}
|
|
262
244
|
|
|
263
245
|
return null;
|
package/lib/isUnique.js
CHANGED
|
@@ -12,6 +12,10 @@ exports.isUnique = isUnique;
|
|
|
12
12
|
*/
|
|
13
13
|
function isUnique(el, selector) {
|
|
14
14
|
if (!Boolean(selector)) return false;
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
try {
|
|
16
|
+
var elems = el.ownerDocument.querySelectorAll(selector);
|
|
17
|
+
return elems.length === 1 && elems[0] === el;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
17
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cypress/unique-selector",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Given a DOM node, return a unique CSS selector matching only that element",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"jsnext:main": "./src/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "git://github.com/
|
|
24
|
+
"url": "git://github.com/cypress-io/unique-selector.git"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"dom",
|
|
@@ -30,13 +30,7 @@
|
|
|
30
30
|
"selector",
|
|
31
31
|
"event"
|
|
32
32
|
],
|
|
33
|
-
"author": "
|
|
34
|
-
"contributors": [
|
|
35
|
-
{
|
|
36
|
-
"name": "Avraam Mavridis",
|
|
37
|
-
"email": "avr.mav@gmail.com"
|
|
38
|
-
}
|
|
39
|
-
],
|
|
33
|
+
"author": "Cypress",
|
|
40
34
|
"license": "MIT",
|
|
41
35
|
"devDependencies": {
|
|
42
36
|
"babel-cli": "^6.26.0",
|