All files / src/utils/Formatters formatterParser.js

51.94% Statements 40/77
33.33% Branches 21/63
100% Functions 5/5
58.2% Lines 39/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126            7x             7x     839x 839x   839x                 703x 703x 703x 703x 703x 703x 703x 703x             703x 17121x 17121x 17121x     17121x     17121x     17121x     17121x           839x   703x 703x   136x     16282x                     16282x                               703x   703x 703x       839x 839x     703x 703x 839x       703x       703x 19978x     703x    
/** Copy from vue/src/compiler/parser/filter-parser.js */
import { noopFormatter } from './Formatter';
import { placeholderFormatter } from './PlaceholderFormatter';
import { dateFormatter } from './DateFormatter';
import { numberFormatter } from './NumberFormatter';
 
const registedFormatters = {
    noop: noopFormatter,
    placeholder: placeholderFormatter,
    date: dateFormatter,
    number: numberFormatter,
};
 
const validDivisionCharRE = /[\w).+\-_$\]]/;
 
function wrapFormatter(exp, filter) {
    const i = filter.indexOf('(');
    if (i < 0) {
    // _f: resolveFilter
        return `_f("${filter}")(${exp})`;
    } else E{
        const name = filter.slice(0, i);
        const args = filter.slice(i + 1);
        return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}`;
    }
}
 
function _parseFormatters(exp) {
    let inSingle = false;
    let inDouble = false;
    let inTemplateString = false;
    let inRegex = false;
    let curly = 0;
    let square = 0;
    let paren = 0;
    let lastFilterIndex = 0;
    let c;
    let prev;
    let i;
    let expression;
    let filters;
 
    for (i = 0; i < exp.length; i++) {
        prev = c;
        c = exp.charCodeAt(i);
        Iif (inSingle) {
            if (c === 0x27 && prev !== 0x5C)
                inSingle = false;
        } else Iif (inDouble) {
            if (c === 0x22 && prev !== 0x5C)
                inDouble = false;
        } else Iif (inTemplateString) {
            if (c === 0x60 && prev !== 0x5C)
                inTemplateString = false;
        } else Iif (inRegex) {
            if (c === 0x2f && prev !== 0x5C)
                inRegex = false;
        } else if (
            c === 0x7C // pipe
      && exp.charCodeAt(i + 1) !== 0x7C
      && exp.charCodeAt(i - 1) !== 0x7C
      && !curly && !square && !paren
        ) {
            if (expression === undefined) {
                // first filter, end of expression
                lastFilterIndex = i + 1;
                expression = exp.slice(0, i).trim();
            } else {
                pushFilter();
            }
        } else {
            switch (c) {
                case 0x22: inDouble = true; break; // "
                case 0x27: inSingle = true; break; // '
                case 0x60: inTemplateString = true; break; // `
                case 0x28: paren++; break; // (
                case 0x29: paren--; break; // )
                case 0x5B: square++; break; // [
                case 0x5D: square--; break; // ]
                case 0x7B: curly++; break; // {
                case 0x7D: curly--; break; // }
            }
            Iif (c === 0x2f) { // /
                let j = i - 1;
                let p;
                // find first non-whitespace prev char
                for (; j >= 0; j--) {
                    p = exp.charAt(j);
                    if (p !== ' ')
                        break;
                }
                if (!p || !validDivisionCharRE.test(p)) {
                    inRegex = true;
                }
            }
        }
    }
 
    Iif (expression === undefined) {
        expression = exp.slice(0, i).trim();
    } else Eif (lastFilterIndex !== 0) {
        pushFilter();
    }
 
    function pushFilter() {
        (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());
        lastFilterIndex = i + 1;
    }
 
    Eif (filters) {
        for (i = 0; i < filters.length; i++) {
            expression = wrapFormatter(expression, filters[i]);
        }
    }
 
    return expression;
}
 
export function parseFormatters(exp) {
    const expression = _parseFormatters('$$VALUE$$ | ' + exp);
    const _f = (name) => registedFormatters[name].format;
 
    /* eslint-disable no-new-func */
    return Function('_f', '$$VALUE$$', `return ${expression}`).bind(null, _f);
}