selectors.js
1 module.exports = { selectorMatchesAnyScope, matcherForSelector }; 2 3 const { isSubset } = require('underscore-plus'); 4 5 // Private: Parse a selector into parts. 6 // If already parsed, returns the selector unmodified. 7 // 8 // * `selector` a {String|Array<String>} specifying what to match 9 // Returns selector parts, an {Array<String>}. 10 function parse(selector) { 11 return typeof selector === 'string' 12 ? selector.replace(/^\./, '').split('.') 13 : selector; 14 } 15 16 const always = scope => true; 17 18 // Essential: Return a matcher function for a selector. 19 // 20 // * selector, a {String} selector 21 // Returns {(scope: String) -> Boolean}, a matcher function returning 22 // true iff the scope matches the selector. 23 function matcherForSelector(selector) { 24 const parts = parse(selector); 25 if (typeof parts === 'function') return parts; 26 return selector ? scope => isSubset(parts, parse(scope)) : always; 27 } 28 29 // Essential: Return true iff the selector matches any provided scope. 30 // 31 // * {String} selector 32 // * {Array<String>} scopes 33 // Returns {Boolean} true if any scope matches the selector. 34 function selectorMatchesAnyScope(selector, scopes) { 35 return !selector || scopes.some(matcherForSelector(selector)); 36 }