1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
8 |
|
9 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
10 |
|
11 | exports.buildPredicate = buildPredicate;
|
12 | exports.reduceTreeBySelector = reduceTreeBySelector;
|
13 | exports.reduceTreesBySelector = reduceTreesBySelector;
|
14 |
|
15 | var _rstSelectorParser = require('rst-selector-parser');
|
16 |
|
17 | var _object = require('object.values');
|
18 |
|
19 | var _object2 = _interopRequireDefault(_object);
|
20 |
|
21 | var _arrayPrototype = require('array.prototype.flat');
|
22 |
|
23 | var _arrayPrototype2 = _interopRequireDefault(_arrayPrototype);
|
24 |
|
25 | var _objectIs = require('object-is');
|
26 |
|
27 | var _objectIs2 = _interopRequireDefault(_objectIs);
|
28 |
|
29 | var _has = require('has');
|
30 |
|
31 | var _has2 = _interopRequireDefault(_has);
|
32 |
|
33 | var _RSTTraversal = require('./RSTTraversal');
|
34 |
|
35 | var _Utils = require('./Utils');
|
36 |
|
37 | var _getAdapter = require('./getAdapter');
|
38 |
|
39 | var _getAdapter2 = _interopRequireDefault(_getAdapter);
|
40 |
|
41 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
42 |
|
43 | 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); } }
|
44 |
|
45 |
|
46 | var parser = (0, _rstSelectorParser.createParser)();
|
47 |
|
48 |
|
49 | var CHILD = 'childCombinator';
|
50 | var ADJACENT_SIBLING = 'adjacentSiblingCombinator';
|
51 | var GENERAL_SIBLING = 'generalSiblingCombinator';
|
52 | var DESCENDANT = 'descendantCombinator';
|
53 |
|
54 |
|
55 | var SELECTOR = 'selector';
|
56 | var TYPE_SELECTOR = 'typeSelector';
|
57 | var CLASS_SELECTOR = 'classSelector';
|
58 | var ID_SELECTOR = 'idSelector';
|
59 | var ATTRIBUTE_PRESENCE = 'attributePresenceSelector';
|
60 | var ATTRIBUTE_VALUE = 'attributeValueSelector';
|
61 |
|
62 | var PSEUDO_CLASS = 'pseudoClassSelector';
|
63 | var PSEUDO_ELEMENT = 'pseudoElementSelector';
|
64 |
|
65 | var EXACT_ATTRIBUTE_OPERATOR = '=';
|
66 | var WHITELIST_ATTRIBUTE_OPERATOR = '~=';
|
67 | var HYPHENATED_ATTRIBUTE_OPERATOR = '|=';
|
68 | var PREFIX_ATTRIBUTE_OPERATOR = '^=';
|
69 | var SUFFIX_ATTRIBUTE_OPERATOR = '$=';
|
70 | var SUBSTRING_ATTRIBUTE_OPERATOR = '*=';
|
71 |
|
72 | function unique(arr) {
|
73 | return [].concat(_toConsumableArray(new Set(arr)));
|
74 | }
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | function uniqueReduce(fn, nodes) {
|
83 | return unique(nodes.reduce(fn, []));
|
84 | }
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 | function safelyGenerateTokens(selector) {
|
92 | try {
|
93 | return parser.parse(selector);
|
94 | } catch (err) {
|
95 | throw new Error('Failed to parse selector: ' + String(selector));
|
96 | }
|
97 | }
|
98 |
|
99 | function matchAttributeSelector(node, token) {
|
100 | var operator = token.operator,
|
101 | value = token.value,
|
102 | name = token.name;
|
103 |
|
104 | var nodeProps = (0, _Utils.propsOfNode)(node);
|
105 | var descriptor = Object.getOwnPropertyDescriptor(nodeProps, name);
|
106 | if (descriptor && descriptor.get) {
|
107 | return false;
|
108 | }
|
109 | var nodePropValue = nodeProps[name];
|
110 | if (typeof nodePropValue === 'undefined') {
|
111 | return false;
|
112 | }
|
113 | if (token.type === ATTRIBUTE_PRESENCE) {
|
114 | return (0, _has2['default'])(nodeProps, token.name);
|
115 | }
|
116 |
|
117 | if (typeof nodePropValue !== 'string' || typeof value !== 'string') {
|
118 | if (operator !== EXACT_ATTRIBUTE_OPERATOR) {
|
119 | return false;
|
120 | }
|
121 | }
|
122 | switch (operator) {
|
123 | |
124 |
|
125 |
|
126 |
|
127 |
|
128 | case EXACT_ATTRIBUTE_OPERATOR:
|
129 | return (0, _objectIs2['default'])(nodePropValue, value);
|
130 | |
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 | case WHITELIST_ATTRIBUTE_OPERATOR:
|
137 | return nodePropValue.split(' ').indexOf(value) !== -1;
|
138 | |
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 | case HYPHENATED_ATTRIBUTE_OPERATOR:
|
145 | return nodePropValue === value || nodePropValue.startsWith(String(value) + '-');
|
146 | |
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | case PREFIX_ATTRIBUTE_OPERATOR:
|
153 | return value === '' ? false : nodePropValue.slice(0, value.length) === value;
|
154 | |
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 | case SUFFIX_ATTRIBUTE_OPERATOR:
|
161 | return value === '' ? false : nodePropValue.slice(-value.length) === value;
|
162 | |
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | case SUBSTRING_ATTRIBUTE_OPERATOR:
|
170 | return value === '' ? false : nodePropValue.indexOf(value) !== -1;
|
171 | default:
|
172 | throw new Error('Enzyme::Selector: Unknown attribute selector operator "' + String(operator) + '"');
|
173 | }
|
174 | }
|
175 |
|
176 | function matchPseudoSelector(node, token, root) {
|
177 | var name = token.name,
|
178 | parameters = token.parameters;
|
179 |
|
180 | if (name === 'not') {
|
181 |
|
182 | return parameters.every(function (selector) {
|
183 | return reduceTreeBySelector(selector, node).length === 0;
|
184 | });
|
185 | }
|
186 | if (name === 'empty') {
|
187 | return (0, _RSTTraversal.treeFilter)(node, function (n) {
|
188 | return n !== node;
|
189 | }).length === 0;
|
190 | }
|
191 | if (name === 'first-child') {
|
192 | var _findParentNode = (0, _RSTTraversal.findParentNode)(root, node),
|
193 | rendered = _findParentNode.rendered;
|
194 |
|
195 | var _rendered = _slicedToArray(rendered, 1),
|
196 | firstChild = _rendered[0];
|
197 |
|
198 | return firstChild === node;
|
199 | }
|
200 | if (name === 'last-child') {
|
201 | var _findParentNode2 = (0, _RSTTraversal.findParentNode)(root, node),
|
202 | _rendered2 = _findParentNode2.rendered;
|
203 |
|
204 | return _rendered2[_rendered2.length - 1] === node;
|
205 | }
|
206 |
|
207 | throw new TypeError('Enzyme::Selector does not support the "' + String(token.name) + '" pseudo-element or pseudo-class selectors.');
|
208 | }
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | function nodeMatchesToken(node, token, root) {
|
217 | if (node === null || typeof node === 'string') {
|
218 | return false;
|
219 | }
|
220 | switch (token.type) {
|
221 | |
222 |
|
223 |
|
224 |
|
225 | case CLASS_SELECTOR:
|
226 | return (0, _RSTTraversal.hasClassName)(node, token.name);
|
227 | |
228 |
|
229 |
|
230 |
|
231 | case TYPE_SELECTOR:
|
232 | return (0, _Utils.nodeHasType)(node, token.name);
|
233 | |
234 |
|
235 |
|
236 |
|
237 | case ID_SELECTOR:
|
238 | return (0, _RSTTraversal.nodeHasId)(node, token.name);
|
239 | |
240 |
|
241 |
|
242 |
|
243 |
|
244 | case ATTRIBUTE_PRESENCE:
|
245 | return matchAttributeSelector(node, token);
|
246 | |
247 |
|
248 |
|
249 |
|
250 |
|
251 | case ATTRIBUTE_VALUE:
|
252 | return matchAttributeSelector(node, token);
|
253 | case PSEUDO_ELEMENT:
|
254 | case PSEUDO_CLASS:
|
255 | return matchPseudoSelector(node, token, root);
|
256 | default:
|
257 | throw new Error('Unknown token type: ' + String(token.type));
|
258 | }
|
259 | }
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 | function buildPredicateFromToken(token, root) {
|
268 | return function (node) {
|
269 | return token.body.every(function (bodyToken) {
|
270 | return nodeMatchesToken(node, bodyToken, root);
|
271 | });
|
272 | };
|
273 | }
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 | function isComplexSelector(tokens) {
|
281 | return tokens.some(function (token) {
|
282 | return token.type !== SELECTOR;
|
283 | });
|
284 | }
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 | function buildPredicate(selector) {
|
293 |
|
294 | if (typeof selector === 'string') {
|
295 | var tokens = safelyGenerateTokens(selector);
|
296 | if (isComplexSelector(tokens)) {
|
297 | throw new TypeError('This method does not support complex CSS selectors');
|
298 | }
|
299 |
|
300 | return buildPredicateFromToken(tokens[0]);
|
301 | }
|
302 |
|
303 |
|
304 | var adapter = (0, _getAdapter2['default'])();
|
305 | var isElementType = adapter.isValidElementType ? adapter.isValidElementType(selector) : typeof selector === 'function';
|
306 | if (isElementType) {
|
307 | return function (node) {
|
308 | return node && node.type === selector;
|
309 | };
|
310 | }
|
311 |
|
312 | if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) === 'object') {
|
313 | if (!Array.isArray(selector) && selector !== null && Object.keys(selector).length > 0) {
|
314 | var hasUndefinedValues = (0, _object2['default'])(selector).some(function (value) {
|
315 | return typeof value === 'undefined';
|
316 | });
|
317 | if (hasUndefinedValues) {
|
318 | throw new TypeError('Enzyme::Props can’t have `undefined` values. Try using ‘findWhere()’ instead.');
|
319 | }
|
320 | return function (node) {
|
321 | return (0, _RSTTraversal.nodeMatchesObjectProps)(node, selector);
|
322 | };
|
323 | }
|
324 | throw new TypeError('Enzyme::Selector does not support an array, null, or empty object as a selector');
|
325 | }
|
326 |
|
327 | throw new TypeError('Enzyme::Selector expects a string, object, or valid element type (Component Constructor)');
|
328 | }
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 |
|
337 | function matchAdjacentSiblings(nodes, predicate, root) {
|
338 | return nodes.reduce(function (matches, node) {
|
339 | var parent = (0, _RSTTraversal.findParentNode)(root, node);
|
340 |
|
341 | if (!parent) {
|
342 | return matches;
|
343 | }
|
344 | var parentChildren = (0, _RSTTraversal.childrenOfNode)(parent);
|
345 | var nodeIndex = parentChildren.indexOf(node);
|
346 | var adjacentSibling = parentChildren[nodeIndex + 1];
|
347 |
|
348 | if (!adjacentSibling) {
|
349 | return matches;
|
350 | }
|
351 | if (predicate(adjacentSibling)) {
|
352 | matches.push(adjacentSibling);
|
353 | }
|
354 | return matches;
|
355 | }, []);
|
356 | }
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | function matchGeneralSibling(nodes, predicate, root) {
|
366 | return uniqueReduce(function (matches, node) {
|
367 | var parent = (0, _RSTTraversal.findParentNode)(root, node);
|
368 | if (!parent) {
|
369 | return matches;
|
370 | }
|
371 | var parentChildren = (0, _RSTTraversal.childrenOfNode)(parent);
|
372 | var nodeIndex = parentChildren.indexOf(node);
|
373 | var youngerSiblings = parentChildren.slice(nodeIndex + 1);
|
374 | return matches.concat(youngerSiblings.filter(predicate));
|
375 | }, nodes);
|
376 | }
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 | function matchDirectChild(nodes, predicate) {
|
385 | return uniqueReduce(function (matches, node) {
|
386 | return matches.concat((0, _RSTTraversal.childrenOfNode)(node).filter(predicate));
|
387 | }, nodes);
|
388 | }
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 | function matchDescendant(nodes, predicate) {
|
397 | return uniqueReduce(function (matches, node) {
|
398 | return matches.concat((0, _RSTTraversal.treeFilter)(node, predicate));
|
399 | }, (0, _arrayPrototype2['default'])(nodes.map(_RSTTraversal.childrenOfNode)));
|
400 | }
|
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 |
|
410 | function reduceTreeBySelector(selector, root) {
|
411 | if (typeof selector === 'function' || (typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) === 'object') {
|
412 | return (0, _RSTTraversal.treeFilter)(root, buildPredicate(selector));
|
413 | }
|
414 |
|
415 | var results = [];
|
416 | if (typeof selector === 'string') {
|
417 | var tokens = safelyGenerateTokens(selector);
|
418 | var index = 0;
|
419 | while (index < tokens.length) {
|
420 | var token = tokens[index];
|
421 | |
422 |
|
423 |
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 |
|
434 |
|
435 | if (token.type === SELECTOR) {
|
436 | var predicate = buildPredicateFromToken(token, root);
|
437 | results = results.concat((0, _RSTTraversal.treeFilter)(root, predicate));
|
438 | } else {
|
439 |
|
440 |
|
441 | var type = token.type;
|
442 |
|
443 |
|
444 |
|
445 | index += 1;
|
446 | var _predicate = buildPredicateFromToken(tokens[index], root);
|
447 |
|
448 |
|
449 | switch (type) {
|
450 |
|
451 | case ADJACENT_SIBLING:
|
452 | results = matchAdjacentSiblings(results, _predicate, root);
|
453 | break;
|
454 |
|
455 | case GENERAL_SIBLING:
|
456 | results = matchGeneralSibling(results, _predicate, root);
|
457 | break;
|
458 |
|
459 | case CHILD:
|
460 | results = matchDirectChild(results, _predicate);
|
461 | break;
|
462 |
|
463 | case DESCENDANT:
|
464 | {
|
465 | results = matchDescendant(results, _predicate);
|
466 | break;
|
467 | }
|
468 | default:
|
469 | throw new Error('Unknown combinator selector: ' + String(type));
|
470 | }
|
471 | }
|
472 | index += 1;
|
473 | }
|
474 | } else {
|
475 | throw new TypeError('Enzyme::Selector expects a string, object, or Component Constructor');
|
476 | }
|
477 | return results;
|
478 | }
|
479 |
|
480 | function reduceTreesBySelector(selector, roots) {
|
481 | var results = roots.map(function (n) {
|
482 | return reduceTreeBySelector(selector, n);
|
483 | });
|
484 | return unique((0, _arrayPrototype2['default'])(results, 1));
|
485 | } |
\ | No newline at end of file |