forked from gajus/surgeon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselectSubroutine.js
48 lines (37 loc) · 1.29 KB
/
selectSubroutine.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// @flow
import {
FinalResultSentinel,
} from 'pianola';
import {
createQuantifier,
} from '../factories';
import {
SelectSubroutineUnexpectedResultCountError,
SurgeonError,
} from '../errors';
import type {
SubroutineType,
} from '../types';
import Logger from '../Logger';
const log = Logger.child({
namespace: 'subroutine:select',
});
const selectSubroutine: SubroutineType = (subject, [cssSelector, quantifierExpression], {evaluator}) => {
log.debug('selecting "%s"', cssSelector);
if (!evaluator.isElement(subject)) {
throw new SurgeonError('Unexpected value. Value must be an element.');
}
const matches = evaluator.querySelectorAll(subject, cssSelector);
const quantifier = createQuantifier(quantifierExpression);
log.debug('selector "%s" matched %d node(s)', cssSelector, matches.length);
if (matches.length < quantifier.min || matches.length > quantifier.max) {
log.debug('expected to match between %d and %s matches', quantifier.min, quantifier.max === Infinity ? 'infinity' : quantifier.max);
throw new SelectSubroutineUnexpectedResultCountError(matches.length, quantifier);
}
if (quantifier.index === null) {
return matches;
} else {
return matches[quantifier.index] || new FinalResultSentinel(null);
}
};
export default selectSubroutine;