weex-styler
Advanced tools
Comparing version 0.1.3 to 0.1.4
38
index.js
'use strict' | ||
var css = require('css') | ||
var util = require('./lib/util') | ||
var validateItem = require('./lib/validator').validate | ||
var css = require('css') | ||
function extend(dest, src) { | ||
var ret = {} | ||
for (var i in dest) { | ||
ret[i] = dest[i] | ||
} | ||
for (var i in src) { | ||
ret[i] = src[i] | ||
} | ||
return ret | ||
} | ||
/** | ||
@@ -79,6 +67,5 @@ * Parse `<style>` code to a JSON Object and log errors & warnings | ||
// catch unsupported selectors | ||
rule.selectors.forEach(function (selector) { | ||
if (selector.match(/^\.[A-Za-z0-9_\-:]+$/)) { | ||
var className = selector.substr(1) | ||
var className = selector.slice(1) | ||
@@ -97,8 +84,16 @@ // handle pseudo class | ||
if (!jsonStyle[className]) { | ||
jsonStyle[className] = ruleResult | ||
} | ||
else { | ||
jsonStyle[className] = extend(jsonStyle[className], ruleResult) | ||
} | ||
// merge style | ||
Object.keys(ruleResult).forEach(function (prop) { | ||
if (prop.indexOf('transition') === 0) { // handle transition | ||
var realProp = prop.replace('transition', '') | ||
realProp = realProp[0].toLowerCase() + realProp.slice(1) | ||
jsonStyle['@TRANSITION'] = jsonStyle['@TRANSITION'] || {} | ||
jsonStyle['@TRANSITION'][className] = jsonStyle['@TRANSITION'][className] || {} | ||
jsonStyle['@TRANSITION'][className][realProp] = ruleResult[prop] | ||
} | ||
else { | ||
jsonStyle[className] = jsonStyle[className] || {} | ||
jsonStyle[className][prop] = ruleResult[prop] | ||
} | ||
}) | ||
} | ||
@@ -138,2 +133,3 @@ else { | ||
} | ||
done(err, {jsonStyle: jsonStyle, log: log}) | ||
@@ -140,0 +136,0 @@ } |
@@ -178,3 +178,3 @@ var util = require('./util') | ||
/** | ||
* the values above is valid | ||
* the values below is valid | ||
* - number | ||
@@ -185,3 +185,3 @@ * - number + 'px' | ||
* @return {function} a function to return | ||
* - value:string|null | ||
* - value: number|null | ||
* - reason(k, v, result) | ||
@@ -220,3 +220,3 @@ */ | ||
/** | ||
* the values above is valid | ||
* the values below is valid | ||
* - hex color value (#xxxxxx or #xxx) | ||
@@ -227,3 +227,3 @@ * - basic and extended color keywords in CSS spec | ||
* @return {function} a function to return | ||
* - value:string|null | ||
* - value: string|null | ||
* - reason(k, v, result) | ||
@@ -293,3 +293,3 @@ */ | ||
* @return {function} a function to return | ||
* - value:string|null | ||
* - value: number|null | ||
* - reason(k, v, result) | ||
@@ -318,3 +318,3 @@ */ | ||
* @return {function} a function to return | ||
* - value:string|null | ||
* - value: number|null | ||
* - reason(k, v, result) | ||
@@ -338,2 +338,84 @@ */ | ||
/** | ||
* 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 = util.hyphenedToCamelCase(v) | ||
for (var prop in validatorMap) { | ||
if (prop === v) { | ||
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 || '0s').toString() | ||
var match | ||
if (match = v.match(/^[0-9]*\.?[0-9]+(ms|s)$/)) { | ||
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 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 = /^[-]?[0-9]*\.?[0-9]+$/ | ||
if (match = v.match(/^cubic-bezier\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*\)$/)) { | ||
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)`)' | ||
} | ||
} | ||
} | ||
/** | ||
* generate a function to check whether a value is in `list` | ||
@@ -345,3 +427,3 @@ * - first value: default, could be removed | ||
* @return {function} a function(v) which returns a function to return | ||
* - value:string|null | ||
* - value: string|null | ||
* - reason(k, v, result) | ||
@@ -432,2 +514,8 @@ */ | ||
}, | ||
transition: { | ||
transitionProperty: TRANSITION_PROPERTY_VALIDATOR, | ||
transitionDuration: TRANSITION_INTERVAL_VALIDATOR, | ||
transitionDelay: TRANSITION_INTERVAL_VALIDATOR, | ||
transitionTimingFunction: TRANSITION_TIMING_FUNCTION_VALIDATOR | ||
}, | ||
customized: { | ||
@@ -507,2 +595,7 @@ textColor: COLOR_VALIDATOR, | ||
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, | ||
@@ -509,0 +602,0 @@ |
{ | ||
"name": "weex-styler", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "Weex <style> transformer", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -75,2 +75,31 @@ var chai = require('chai') | ||
it('parse transition', function (done) { | ||
var code = '.foo {transition-property: margin-top; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in;}' | ||
styler.parse(code, function (err, data) { | ||
expect(err).is.undefined | ||
expect(data).is.an.object | ||
expect(data.jsonStyle).eql({'@TRANSITION': {foo: {property: 'marginTop', duration: '300ms', delay: '0.2s', timingFunction: 'ease-in'}}}) | ||
expect(data.log).eql([]) | ||
done() | ||
}) | ||
}) | ||
it('parse complex transition', function (done) { | ||
var code = '.foo {font-size: 20; color: #000000}\n\n .foo, .bar {color: #ff5000; height: 30; transition-property: margin-top; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in;}' | ||
styler.parse(code, function (err, data) { | ||
expect(err).is.undefined | ||
expect(data).is.an.object | ||
expect(data.jsonStyle).eql({ | ||
'@TRANSITION': { | ||
foo: {property: 'marginTop', duration: '300ms', delay: '0.2s', timingFunction: 'ease-in'}, | ||
bar: {property: 'marginTop', duration: '300ms', delay: '0.2s', timingFunction: 'ease-in'} | ||
}, | ||
foo: {fontSize: 20, color: '#ff5000', height: 30}, | ||
bar: {color: '#ff5000', height: 30} | ||
}) | ||
expect(data.log).eql([]) | ||
done() | ||
}) | ||
}) | ||
it('handle pseudo class', function (done) { | ||
@@ -77,0 +106,0 @@ var code = '.class-a {color: #0000ff;} .class-a:last-child:focus {color: #ff0000;}' |
@@ -248,2 +248,93 @@ var chai = require('chai') | ||
it('parse transition-property', function (done) { | ||
var code = { | ||
foo: { | ||
transitionProperty: 'margin-top' | ||
}, | ||
bar: { | ||
transitionProperty: 'height' | ||
}, | ||
baz: { | ||
transitionProperty: 'abc' | ||
} | ||
} | ||
styler.validate(code, function (err, data) { | ||
expect(err).is.undefined | ||
expect(data).is.an.object | ||
expect(data.jsonStyle).eql({ | ||
foo: { | ||
transitionProperty: 'marginTop' | ||
}, | ||
bar: { | ||
transitionProperty: 'height' | ||
}, | ||
baz: {} | ||
}) | ||
expect(data.log).eql([ | ||
{reason: 'ERROR: property value `abc` is not supported for `transition-property` (only css property is valid)'} | ||
]) | ||
done() | ||
}) | ||
}) | ||
it('parse transition-duration & transition-delay', function (done) { | ||
var code = { | ||
foo: { | ||
transitionDuration: '200ms', | ||
transitionDelay: '0.5s' | ||
}, | ||
bar: { | ||
transitionDuration: '200', | ||
transitionDelay: 'abc' | ||
} | ||
} | ||
styler.validate(code, function (err, data) { | ||
expect(err).is.undefined | ||
expect(data).is.an.object | ||
expect(data.jsonStyle).eql({ | ||
foo: { | ||
transitionDuration: '200ms', | ||
transitionDelay: '0.5s' | ||
}, | ||
bar: {} | ||
}) | ||
expect(data.log).eql([ | ||
{reason: 'ERROR: property value `200` is not supported for `transition-duration` (only number of seconds and milliseconds is valid)'}, | ||
{reason: 'ERROR: property value `abc` is not supported for `transition-delay` (only number of seconds and milliseconds is valid)'} | ||
]) | ||
done() | ||
}) | ||
}) | ||
it('parse transition-timing-function', function (done) { | ||
var code = { | ||
foo: { | ||
transitionTimingFunction: 'ease-in-out' | ||
}, | ||
bar: { | ||
transitionTimingFunction: 'cubic-bezier(.88, 1.0, -0.67, 1.37)' | ||
}, | ||
baz: { | ||
transitionTimingFunction: 'abc' | ||
} | ||
} | ||
styler.validate(code, function (err, data) { | ||
expect(err).is.undefined | ||
expect(data).is.an.object | ||
expect(data.jsonStyle).eql({ | ||
foo: { | ||
transitionTimingFunction: 'ease-in-out' | ||
}, | ||
bar: { | ||
transitionTimingFunction: 'cubic-bezier(0.88,1,-0.67,1.37)' | ||
}, | ||
baz: {} | ||
}) | ||
expect(data.log).eql([ | ||
{reason: 'ERROR: property value `abc` is not supported for `transition-timing-function` (supported values are: `linear`|`ease`|`ease-in`|`ease-out`|`ease-in-out`|`cubic-bezier(n,n,n,n)`)'} | ||
]) | ||
done() | ||
}) | ||
}) | ||
it('parse unknown', function (done) { | ||
@@ -250,0 +341,0 @@ var code = { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79564
1280