wecui
Version:
一款基于Vue2.x版本的移动端web组件
189 lines (157 loc) • 3.5 kB
JavaScript
var balanced = require('balanced-match');
var debug = require('debug')('css-color-function:parse');
/**
* Expose `parse`.
*/
module.exports = parse;
/**
* Parse a CSS color function string.
*
* @param {String} string
* @return {Array}
*/
function parse (string) {
if ('string' != typeof string) string = string.toString();
debug('string %s', string);
/**
* Match the current position in the string against a `regexp`, returning the
* match if one exists.
*
* @param {RegExp} regexp
* @return {Undefined or Array}
*/
function match (regexp) {
var m = regexp.exec(string);
if (!m) return;
string = string.slice(m[0].length);
return m.slice(1);
}
/**
* Match whitespace.
*/
function whitespace () {
match(/^\s+/);
}
/**
* Match a right parentheses.
*
* @return {Array or Undefined}
*/
function rparen () {
var m = match(/^\)/);
if (!m) return;
debug('rparen');
return m;
}
/**
* Match a modifier: '+' '-' '*'.
*
* @return {Object or Undefined}
*/
function modifier () {
var m = match(/^([\+\-\*])/);
if (!m) return;
var ret = {};
ret.type = 'modifier';
ret.value = m[0];
debug('modifier %o', ret);
return ret;
}
/**
* Match a generic number function argument.
*
* @return {Object or Undefined}
*/
function number () {
var m = match(/^([^\)\s]+)/);
if (!m) return;
var ret = {};
ret.type = 'number';
ret.value = m[0];
debug('number %o', ret);
return ret;
}
/**
* Match a function's arguments.
*
* @return {Array}
*/
function args () {
var ret = [];
var el;
while (el = modifier() || fn() || number()) {
ret.push(el);
whitespace();
}
debug('args %o', ret);
return ret;
}
/**
* Match an adjuster function.
*
* @return {Object or Undefined}
*/
function adjuster () {
var m = match(/^(\w+)\(/);
if (!m) return;
whitespace();
var el;
var ret = {};
ret.type = 'function';
ret.name = m[0];
ret.arguments = args();
rparen()
debug('adjuster %o', ret);
return ret;
}
/**
* Match a color.
*
* @return {Object}
*/
function color () {
var ret = {};
ret.type = 'color';
var col = match(/([^\)\s]+)/)[0];
if (col.indexOf('(') != -1) {
var piece = match(/([^\)]*?\))/)[0];
col = col + piece;
}
ret.value = col;
whitespace();
return ret;
}
/**
* Match a color function, capturing the first color argument and any adjuster
* functions after it.
*
* @return {Object or Undefined}
*/
function fn () {
if (!string.match(/^color\(/)) return;
var colorRef = balanced('(', ')', string)
if (!colorRef) throw new SyntaxError('Missing closing parenthese for \'' + string + '\'');
if (colorRef.body === '') throw new SyntaxError('color() function cannot be empty');
string = colorRef.body
whitespace();
var ret = {};
ret.type = 'function';
ret.name = 'color';
ret.arguments = [fn() || color()];
debug('function arguments %o', ret.arguments);
var el;
while (el = adjuster()) {
ret.arguments.push(el);
whitespace();
}
// pass the rest of the string in case of recursive color()
string = colorRef.post
whitespace();
debug('function %o', ret);
return ret;
}
/**
* Return the parsed color function.
*/
return fn();
}