智能照明系统APP-本地串口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
LightingSystemApp-serial/.svn/pristine/43/4344d156aa051f24b7afc7301c6...

724 lines
19 KiB

var util = require('./util')
// http://www.w3.org/TR/css3-color/#html4
var BASIC_COLOR_KEYWORDS = {
black: '#000000',
silver: '#C0C0C0',
gray: '#808080',
white: '#FFFFFF',
maroon: '#800000',
red: '#FF0000',
purple: '#800080',
fuchsia: '#FF00FF',
green: '#008000',
lime: '#00FF00',
olive: '#808000',
yellow: '#FFFF00',
navy: '#000080',
blue: '#0000FF',
teal: '#008080',
aqua: '#00FFFF'
}
// http://www.w3.org/TR/css3-color/#svg-color
var EXTENDED_COLOR_KEYWORDS = {
aliceblue: '#F0F8FF',
antiquewhite: '#FAEBD7',
aqua: '#00FFFF',
aquamarine: '#7FFFD4',
azure: '#F0FFFF',
beige: '#F5F5DC',
bisque: '#FFE4C4',
black: '#000000',
blanchedalmond: '#FFEBCD',
blue: '#0000FF',
blueviolet: '#8A2BE2',
brown: '#A52A2A',
burlywood: '#DEB887',
cadetblue: '#5F9EA0',
chartreuse: '#7FFF00',
chocolate: '#D2691E',
coral: '#FF7F50',
cornflowerblue: '#6495ED',
cornsilk: '#FFF8DC',
crimson: '#DC143C',
cyan: '#00FFFF',
darkblue: '#00008B',
darkcyan: '#008B8B',
darkgoldenrod: '#B8860B',
darkgray: '#A9A9A9',
darkgreen: '#006400',
darkgrey: '#A9A9A9',
darkkhaki: '#BDB76B',
darkmagenta: '#8B008B',
darkolivegreen: '#556B2F',
darkorange: '#FF8C00',
darkorchid: '#9932CC',
darkred: '#8B0000',
darksalmon: '#E9967A',
darkseagreen: '#8FBC8F',
darkslateblue: '#483D8B',
darkslategray: '#2F4F4F',
darkslategrey: '#2F4F4F',
darkturquoise: '#00CED1',
darkviolet: '#9400D3',
deeppink: '#FF1493',
deepskyblue: '#00BFFF',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1E90FF',
firebrick: '#B22222',
floralwhite: '#FFFAF0',
forestgreen: '#228B22',
fuchsia: '#FF00FF',
gainsboro: '#DCDCDC',
ghostwhite: '#F8F8FF',
gold: '#FFD700',
goldenrod: '#DAA520',
gray: '#808080',
green: '#008000',
greenyellow: '#ADFF2F',
grey: '#808080',
honeydew: '#F0FFF0',
hotpink: '#FF69B4',
indianred: '#CD5C5C',
indigo: '#4B0082',
ivory: '#FFFFF0',
khaki: '#F0E68C',
lavender: '#E6E6FA',
lavenderblush: '#FFF0F5',
lawngreen: '#7CFC00',
lemonchiffon: '#FFFACD',
lightblue: '#ADD8E6',
lightcoral: '#F08080',
lightcyan: '#E0FFFF',
lightgoldenrodyellow: '#FAFAD2',
lightgray: '#D3D3D3',
lightgreen: '#90EE90',
lightgrey: '#D3D3D3',
lightpink: '#FFB6C1',
lightsalmon: '#FFA07A',
lightseagreen: '#20B2AA',
lightskyblue: '#87CEFA',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#B0C4DE',
lightyellow: '#FFFFE0',
lime: '#00FF00',
limegreen: '#32CD32',
linen: '#FAF0E6',
magenta: '#FF00FF',
maroon: '#800000',
mediumaquamarine: '#66CDAA',
mediumblue: '#0000CD',
mediumorchid: '#BA55D3',
mediumpurple: '#9370DB',
mediumseagreen: '#3CB371',
mediumslateblue: '#7B68EE',
mediumspringgreen: '#00FA9A',
mediumturquoise: '#48D1CC',
mediumvioletred: '#C71585',
midnightblue: '#191970',
mintcream: '#F5FFFA',
mistyrose: '#FFE4E1',
moccasin: '#FFE4B5',
navajowhite: '#FFDEAD',
navy: '#000080',
oldlace: '#FDF5E6',
olive: '#808000',
olivedrab: '#6B8E23',
orange: '#FFA500',
orangered: '#FF4500',
orchid: '#DA70D6',
palegoldenrod: '#EEE8AA',
palegreen: '#98FB98',
paleturquoise: '#AFEEEE',
palevioletred: '#DB7093',
papayawhip: '#FFEFD5',
peachpuff: '#FFDAB9',
peru: '#CD853F',
pink: '#FFC0CB',
plum: '#DDA0DD',
powderblue: '#B0E0E6',
purple: '#800080',
red: '#FF0000',
rosybrown: '#BC8F8F',
royalblue: '#4169E1',
saddlebrown: '#8B4513',
salmon: '#FA8072',
sandybrown: '#F4A460',
seagreen: '#2E8B57',
seashell: '#FFF5EE',
sienna: '#A0522D',
silver: '#C0C0C0',
skyblue: '#87CEEB',
slateblue: '#6A5ACD',
slategray: '#708090',
slategrey: '#708090',
snow: '#FFFAFA',
springgreen: '#00FF7F',
steelblue: '#4682B4',
tan: '#D2B48C',
teal: '#008080',
thistle: '#D8BFD8',
tomato: '#FF6347',
turquoise: '#40E0D0',
violet: '#EE82EE',
wheat: '#F5DEB3',
white: '#FFFFFF',
whitesmoke: '#F5F5F5',
yellow: '#FFFF00',
yellowgreen: '#9ACD32'
}
var LENGTH_REGEXP = /^[-+]?\d*\.?\d+(\S*)$/
var SUPPORT_CSS_UNIT = ['px', 'pt', 'wx']
if(process.env.UNI_USING_NVUE_COMPILER){
SUPPORT_CSS_UNIT.push('upx')
SUPPORT_CSS_UNIT.push('rpx')
}
var ANYTHING_VALIDATOR = function ANYTHING_VALIDATOR(v) {
return { value: v }
}
/**
* the values below is valid
* - number
* - number + 'px'
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var LENGTH_VALIDATOR = function LENGTH_VALIDATOR(v) {
v = (v || '').toString()
var match = v.match(LENGTH_REGEXP)
if (match) {
var unit = match[1]
if (!unit) {
return {value: parseFloat(v)}
}
else if (SUPPORT_CSS_UNIT.indexOf(unit) > -1) {
return {value: v}
}
else {
return {
value: parseFloat(v),
reason: function reason(k, v, result) {
return 'NOTE: unit `' + unit + '` is not supported and property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number and pixel values are supported)'
}
}
}
/**
* the values below is valid
* - number {1,4}
* - number + 'px' {1,4}
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var SHORTHAND_LENGTH_VALIDATOR = function SHORTHAND_LENGTH_VALIDATOR(v) {
v = (v || '').toString()
var value = []
var reason = []
var results = v.split(/\s+/).map(LENGTH_VALIDATOR)
for (var i = 0; i < results.length; ++i) {
var res = results[i]
if (!res.value) {
value = null
reason = res.reason
break
}
value.push(res.value)
reason.push(res.reason)
}
if (!value) {
return {
value: value,
reason: reason
}
} else {
return {
value: value.join(' '),
reason: function (k, v, result) {
return reason.map(function (res) {
if (typeof res === 'function') {
return res(k, v, result)
}
}).join('\n')
}
}
}
}
/**
* the values below is valid
* - hex color value (#xxxxxx or #xxx)
* - basic and extended color keywords in CSS spec
*
* @param {string} v
* @return {function} a function to return
* - value: string|null
* - reason(k, v, result)
*/
var COLOR_VALIDATOR = function COLOR_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^#[0-9a-fA-F]{6}$/)) {
return {value: v}
}
if (v.match(/^#[0-9a-fA-F]{3}$/)) {
return {
value: '#' + v[1] + v[1] + v[2] + v[2] + v[3] + v[3],
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
if (EXTENDED_COLOR_KEYWORDS[v]) {
return {
value: EXTENDED_COLOR_KEYWORDS[v],
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
var arrColor, r, g, b, a
var RGB_REGEXP = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/gi
var RGBA_REGEXP = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d*\.?\d+)\s*\)$/gi
if (arrColor = RGB_REGEXP.exec(v)) {
r = parseInt(arrColor[1])
g = parseInt(arrColor[2])
b = parseInt(arrColor[3])
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
return {value: 'rgb(' + [r, g, b].join(',') + ')'}
}
}
if (arrColor = RGBA_REGEXP.exec(v)) {
r = parseInt(arrColor[1])
g = parseInt(arrColor[2])
b = parseInt(arrColor[3])
a = parseFloat(arrColor[4])
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1) {
return {value: 'rgba(' + [r, g, b, a].join(',') + ')'}
}
}
if (v === 'transparent') {
return {value: 'rgba(0,0,0,0)'}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not valid for `' + util.camelCaseToHyphened(k) + '`'
}
}
}
/**
* only integer or float value is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var NUMBER_VALIDATOR = function NUMBER_VALIDATOR(v) {
v = (v || '').toString()
var match = v.match(LENGTH_REGEXP)
if (match && !match[1]) {
return {value: parseFloat(v)}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number is supported)'
}
}
}
/**
* only integer value is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var INTEGER_VALIDATOR = function INTEGER_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^[-+]?\d+$/)) {
return {value: parseInt(v, 10)}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only integer is supported)'
}
}
}
/**
* transition-property: only css property is valid
*
* @param {string} v
* @return {function} a function to return
* - value: string|null
* - reason(k, v, result)
*/
var TRANSITION_PROPERTY_VALIDATOR = function TRANSITION_PROPERTY_VALIDATOR(v) {
v = (v || '').toString()
v = v.split(/\s*,\s*/).map(util.hyphenedToCamelCase).join(',')
if (v.split(/\s*,\s*/).every(p => !!validatorMap[p])) {
return {value: v}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only css property is valid)'
}
}
}
/**
* transition-duration & transition-delay: only number of seconds or milliseconds is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var TRANSITION_INTERVAL_VALIDATOR = function TRANSITION_INTERVAL_VALIDATOR(v) {
v = (v || 0).toString()
var match, num, ret
if (match = v.match(/^\d*\.?\d+(ms|s)?$/)) {
num = parseFloat(match[0])
if (!match[1]) {
ret = {value: parseInt(num)}
}
else {
if (match[1] === 's') {
num *= 1000
}
ret = {
value: parseInt(num),
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
return ret
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number of seconds and milliseconds is valid)'
}
}
}
/**
* transition-timing-function: only linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n) is valid
*
* @param {string} v
* @return {function} a function to return
* - value: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n)|null
* - reason(k, v, result)
*/
var TRANSITION_TIMING_FUNCTION_VALIDATOR = function TRANSITION_TIMING_FUNCTION_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^linear|ease|ease-in|ease-out|ease-in-out$/)) {
return {value: v}
}
var match, ret
var NUM_REGEXP = /^[-]?\d*\.?\d+$/
if (match = v.match(/^cubic-bezier\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*\)$/)) {
/* istanbul ignore else */
if (match[1].match(NUM_REGEXP) && match[2].match(NUM_REGEXP) && match[3].match(NUM_REGEXP) && match[4].match(NUM_REGEXP)) {
ret = [parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])].join(',')
return {value: 'cubic-bezier(' + ret + ')'}
}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `linear`|`ease`|`ease-in`|`ease-out`|`ease-in-out`|`cubic-bezier(n,n,n,n)`)'
}
}
}
var TRANSFORM_VALIDATOR = function TRANSFORM_VALIDATOR (v) {
// TODO
return { value: v }
}
/**
* generate a function to check whether a value is in `list`
* - first value: default, could be removed
* - not in `list`: error
*
* @param {Array} list
* @return {function} a function(v) which returns a function to return
* - value: string|null
* - reason(k, v, result)
*/
function genEnumValidator(list) {
return function ENUM_VALIDATOR(v) {
var index = list.indexOf(v)
if (index > 0) {
return {value: v}
}
if (index === 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is the DEFAULT value for `' + util.camelCaseToHyphened(k) + '` (could be removed)'
}
}
}
else {
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `' + list.join('`|`') + '`)'
}
}
}
}
}
function FLEW_WRAP_VALIDATOR (v) {
var list = ['nowrap', 'wrap', 'wrap-reverse']
var index = list.indexOf(v)
if (index > 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: the ' + util.camelCaseToHyphened(k) + ' property may have compatibility problem on native'
}
}
}
if (index === 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is the DEFAULT value for `' + util.camelCaseToHyphened(k) + '` (could be removed)'
}
}
}
else {
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `' + list.join('`|`') + '`)'
}
}
}
}
var PROP_NAME_GROUPS = {
boxModel: {
width: LENGTH_VALIDATOR,
height: LENGTH_VALIDATOR,
overflow: genEnumValidator(['hidden']),
padding: SHORTHAND_LENGTH_VALIDATOR,
paddingLeft: LENGTH_VALIDATOR,
paddingRight: LENGTH_VALIDATOR,
paddingTop: LENGTH_VALIDATOR,
paddingBottom: LENGTH_VALIDATOR,
margin: SHORTHAND_LENGTH_VALIDATOR,
marginLeft: LENGTH_VALIDATOR,
marginRight: LENGTH_VALIDATOR,
marginTop: LENGTH_VALIDATOR,
marginBottom: LENGTH_VALIDATOR,
borderWidth: LENGTH_VALIDATOR,
borderLeftWidth: LENGTH_VALIDATOR,
borderTopWidth: LENGTH_VALIDATOR,
borderRightWidth: LENGTH_VALIDATOR,
borderBottomWidth: LENGTH_VALIDATOR,
borderColor: COLOR_VALIDATOR,
borderLeftColor: COLOR_VALIDATOR,
borderTopColor: COLOR_VALIDATOR,
borderRightColor: COLOR_VALIDATOR,
borderBottomColor: COLOR_VALIDATOR,
borderStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderTopStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderRightStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderBottomStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderLeftStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderRadius: LENGTH_VALIDATOR,
borderBottomLeftRadius: LENGTH_VALIDATOR,
borderBottomRightRadius: LENGTH_VALIDATOR,
borderTopLeftRadius: LENGTH_VALIDATOR,
borderTopRightRadius: LENGTH_VALIDATOR
},
flexbox: {
flex: NUMBER_VALIDATOR,
flexWrap: FLEW_WRAP_VALIDATOR,
flexDirection: genEnumValidator(['column', 'row', 'column-reverse', 'row-reverse']),
justifyContent: genEnumValidator(['flex-start', 'flex-end', 'center', 'space-between','space-around']),
alignItems: genEnumValidator(['stretch', 'flex-start', 'flex-end', 'center'])
},
position: {
position: genEnumValidator(['relative', 'absolute', 'sticky', 'fixed']),
top: LENGTH_VALIDATOR,
bottom: LENGTH_VALIDATOR,
left: LENGTH_VALIDATOR,
right: LENGTH_VALIDATOR,
zIndex: INTEGER_VALIDATOR
},
common: {
opacity: NUMBER_VALIDATOR,
boxShadow: ANYTHING_VALIDATOR,
backgroundColor: COLOR_VALIDATOR,
backgroundImage: ANYTHING_VALIDATOR
},
text: {
lines: INTEGER_VALIDATOR,
color: COLOR_VALIDATOR,
fontSize: LENGTH_VALIDATOR,
fontStyle: genEnumValidator(['normal', 'italic']),
fontFamily: ANYTHING_VALIDATOR,
fontWeight: genEnumValidator(['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']),
textDecoration: genEnumValidator(['none', 'underline', 'line-through']),
textAlign: genEnumValidator(['left', 'center', 'right']),
textOverflow: genEnumValidator(['clip', 'ellipsis', 'unset', 'fade']),
lineHeight: LENGTH_VALIDATOR
},
transition: {
transitionProperty: TRANSITION_PROPERTY_VALIDATOR,
transitionDuration: TRANSITION_INTERVAL_VALIDATOR,
transitionDelay: TRANSITION_INTERVAL_VALIDATOR,
transitionTimingFunction: TRANSITION_TIMING_FUNCTION_VALIDATOR
},
transform: {
transform: TRANSFORM_VALIDATOR,
transformOrigin: TRANSFORM_VALIDATOR,// fixed by xxxxxx
},
customized: {
itemSize: LENGTH_VALIDATOR,
itemColor: COLOR_VALIDATOR,
itemSelectedColor: COLOR_VALIDATOR,
textColor: COLOR_VALIDATOR,
timeColor: COLOR_VALIDATOR,
textHighlightColor: COLOR_VALIDATOR
}
}
var SUGGESTED_PROP_NAME_GROUP = {
background: 'backgroundColor'
}
var validatorMap = {}
/**
* flatten `PROP_NAME_GROUPS` to `validatorMap`
*/
function genValidatorMap() {
var groupName, group, name
for (groupName in PROP_NAME_GROUPS) {
group = PROP_NAME_GROUPS[groupName]
for (name in group) {
validatorMap[name] = group[name]
}
}
}
genValidatorMap()
/**
* validate a CSS name/value pair
*
* @param {string} name camel cased
* @param {string} value
* @return {object}
* - value:string or null
* - log:{reason:string} or undefined
*/
function validate(name, value) {
var result, log
var validator = validatorMap[name]
if (typeof validator === 'function') {
if (typeof value !== 'function') {
result = validator(value)
}
/* istanbul ignore else */
else {
result = {value: value}
}
if (result.reason) {
log = {reason: result.reason(name, value, result.value)}
}
}
else {
// ensure number type, no `px`
/* istanbul ignore else */
if (typeof value !== 'function') {
var match = value.match(LENGTH_REGEXP)
if (match && (!match[1] || SUPPORT_CSS_UNIT.indexOf(match[1]) === -1)) {
value = parseFloat(value)
}
}
result = {value: value}
var suggestedName = SUGGESTED_PROP_NAME_GROUP[name]
var suggested = suggestedName ? ', suggest `' + util.camelCaseToHyphened(suggestedName) + '`' : ''
log = {reason: 'WARNING: `' + util.camelCaseToHyphened(name) + '` is not a standard property name (may not be supported)' + suggested}
}
return {
value: result.value,
log: log
}
}
module.exports = {
BASIC_COLOR_KEYWORDS: BASIC_COLOR_KEYWORDS,
EXTENDED_COLOR_KEYWORDS: EXTENDED_COLOR_KEYWORDS,
LENGTH_VALIDATOR: LENGTH_VALIDATOR,
COLOR_VALIDATOR: COLOR_VALIDATOR,
NUMBER_VALIDATOR: NUMBER_VALIDATOR,
INTEGER_VALIDATOR: INTEGER_VALIDATOR,
genEnumValidator: genEnumValidator,
TRANSITION_PROPERTY_VALIDATOR: TRANSITION_PROPERTY_VALIDATOR,
TRANSITION_DURATION_VALIDATOR: TRANSITION_INTERVAL_VALIDATOR,
TRANSITION_DELAY_VALIDATOR: TRANSITION_INTERVAL_VALIDATOR,
TRANSITION_TIMING_FUNCTION_VALIDATOR: TRANSITION_TIMING_FUNCTION_VALIDATOR,
PROP_NAME_GROUPS: PROP_NAME_GROUPS,
map: validatorMap,
validate: validate
}