'use strict'; const genericConst = require('./generic-const.cjs'); const genericAnPlusB = require('./generic-an-plus-b.cjs'); const genericUrange = require('./generic-urange.cjs'); const types = require('../tokenizer/types.cjs'); const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); const utils = require('../tokenizer/utils.cjs'); const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc(']; const balancePair = new Map([ [types.Function, types.RightParenthesis], [types.LeftParenthesis, types.RightParenthesis], [types.LeftSquareBracket, types.RightSquareBracket], [types.LeftCurlyBracket, types.RightCurlyBracket] ]); // safe char code getter function charCodeAt(str, index) { return index < str.length ? str.charCodeAt(index) : 0; } function eqStr(actual, expected) { return utils.cmpStr(actual, 0, actual.length, expected); } function eqStrAny(actual, expected) { for (let i = 0; i < expected.length; i++) { if (eqStr(actual, expected[i])) { return true; } } return false; } // IE postfix hack, i.e. 123\0 or 123px\9 function isPostfixIeHack(str, offset) { if (offset !== str.length - 2) { return false; } return ( charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\) charCodeDefinitions.isDigit(charCodeAt(str, offset + 1)) ); } function outOfRange(opts, value, numEnd) { if (opts && opts.type === 'Range') { const num = Number( numEnd !== undefined && numEnd !== value.length ? value.substr(0, numEnd) : value ); if (isNaN(num)) { return true; } // FIXME: when opts.min is a string it's a dimension, skip a range validation // for now since it requires a type covertation which is not implmented yet if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') { return true; } // FIXME: when opts.max is a string it's a dimension, skip a range validation // for now since it requires a type covertation which is not implmented yet if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') { return true; } } return false; } function consumeFunction(token, getNextToken) { let balanceCloseType = 0; let balanceStash = []; let length = 0; // balanced token consuming scan: do { switch (token.type) { case types.RightCurlyBracket: case types.RightParenthesis: case types.RightSquareBracket: if (token.type !== balanceCloseType) { break scan; } balanceCloseType = balanceStash.pop(); if (balanceStash.length === 0) { length++; break scan; } break; case types.Function: case types.LeftParenthesis: case types.LeftSquareBracket: case types.LeftCurlyBracket: balanceStash.push(balanceCloseType); balanceCloseType = balancePair.get(token.type); break; } length++; } while (token = getNextToken(length)); return length; } // TODO: implement // can be used wherever , , ,