stylelint-taro-rn
Version:
A collection of React Native specific rules for stylelint
73 lines (62 loc) • 2.27 kB
JavaScript
/**
* Compares a string to a second value that, if it fits a certain convention,
* is converted to a regular expression before the comparison.
* If it doesn't fit the convention, then two strings are compared.
*
* Any strings starting and ending with `/` are interpreted
* as regular expressions.
*/
export function matchesStringOrRegExp (
input /*: string | Array<string> */,
comparison /*: string | Array<string> */
) /*: false | { match: string, pattern: string } */ {
if (!Array.isArray(input)) {
return testAgainstStringOrRegExpOrArray(input, comparison)
}
for (const inputItem of input) {
const testResult = testAgainstStringOrRegExpOrArray(inputItem, comparison)
if (testResult) {
return testResult
}
}
return false
}
function testAgainstStringOrRegExpOrArray (value, comparison) {
if (!Array.isArray(comparison)) {
return testAgainstStringOrRegExp(value, comparison)
}
for (const comparisonItem of comparison) {
const testResult = testAgainstStringOrRegExp(value, comparisonItem)
if (testResult) {
return testResult
}
}
return false
}
function testAgainstStringOrRegExp (value, comparison) {
// If it's a RegExp, test directly
if (comparison instanceof RegExp) {
return comparison.test(value)
? { match: value, pattern: comparison }
: false
}
// Check if it's RegExp in a string
const firstComparisonChar = comparison[0]
const lastComparisonChar = comparison[comparison.length - 1]
const secondToLastComparisonChar = comparison[comparison.length - 2]
const comparisonIsRegex =
firstComparisonChar === '/' &&
(lastComparisonChar === '/' ||
(secondToLastComparisonChar === '/' && lastComparisonChar === 'i'))
const hasCaseInsensitiveFlag =
comparisonIsRegex && lastComparisonChar === 'i'
// If so, create a new RegExp from it
if (comparisonIsRegex) {
const valueMatches = hasCaseInsensitiveFlag
? new RegExp(comparison.slice(1, -2), 'i').test(value)
: new RegExp(comparison.slice(1, -1)).test(value)
return valueMatches ? { match: value, pattern: comparison } : false
}
// Otherwise, it's a string. Do a strict comparison
return value === comparison ? { match: value, pattern: comparison } : false
}