function findMatch()

in static/api/admin/4.0.x/search.js [160:216]


function findMatch(matcher, input, startOfName, endOfName) {
    var from = startOfName;
    matcher.lastIndex = from;
    var match = matcher.exec(input);
    // Expand search area until we get a valid result or reach the beginning of the string
    while (!match || match.index + match[0].length < startOfName || endOfName < match.index) {
        if (from === 0) {
            return NO_MATCH;
        }
        from = input.lastIndexOf(".", from - 2) + 1;
        matcher.lastIndex = from;
        match = matcher.exec(input);
    }
    var boundaries = [];
    var matchEnd = match.index + match[0].length;
    var score = 5;
    var start = match.index;
    var prevEnd = -1;
    for (var i = 1; i < match.length; i += 2) {
        var isUpper = isUpperCase(input[start]);
        var isMatcherUpper = matcher.upperCase[i];
        // capturing groups come in pairs, match and non-match
        boundaries.push(start, start + match[i].length);
        // make sure groups are anchored on a left word boundary
        var prevChar = input[start - 1] || "";
        var nextChar = input[start + 1] || "";
        if (start !== 0 && !/[\W_]/.test(prevChar) && !/[\W_]/.test(input[start])) {
            if (isUpper && (isLowerCase(prevChar) || isLowerCase(nextChar))) {
                score -= 0.1;
            } else if (isMatcherUpper && start === prevEnd) {
                score -= isUpper ? 0.1 : 1.0;
            } else {
                return NO_MATCH;
            }
        }
        prevEnd = start + match[i].length;
        start += match[i].length + match[i + 1].length;

        // lower score for parts of the name that are missing
        if (match[i + 1] && prevEnd < endOfName) {
            score -= rateNoise(match[i + 1]);
        }
    }
    // lower score if a type name contains unmatched camel-case parts
    if (input[matchEnd - 1] !== "." && endOfName > matchEnd)
        score -= rateNoise(input.slice(matchEnd, endOfName));
    score -= rateNoise(input.slice(0, Math.max(startOfName, match.index)));

    if (score <= 0) {
        return NO_MATCH;
    }
    return {
        input: input,
        score: score,
        boundaries: boundaries
    };
}