Skip to content

Commit a7aabe0

Browse files
luxpHanks10100
authored andcommitted
Support margin (#15)
* add .idea to .gitignore * move transition shorthand parse to ./lib/shorthand-parser.js * add test for shorthand-parser * support margin
1 parent 7f7d2fe commit a7aabe0

File tree

4 files changed

+241
-18
lines changed

4 files changed

+241
-18
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
coverage
33
.DS_Store
4+
.idea

index.js

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
var css = require('css')
44
var util = require('./lib/util')
55
var validateItem = require('./lib/validator').validate
6+
var shorthandParser = require('./lib/shorthand-parser')
67

78
// padding & margin shorthand parsing
89
function convertLengthShorthand (rule, prop) {
@@ -58,24 +59,7 @@ function parse(code, done) {
5859

5960
if (type === 'rule') {
6061
if (rule.declarations && rule.declarations.length) {
61-
// transition shorthand parsing
62-
var CHUNK_REGEXP = /^(\S*)?\s*(\d*\.?\d+(?:ms|s)?)?\s*(\S*)?\s*(\d*\.?\d+(?:ms|s)?)?$/
63-
for (var i = 0; i < rule.declarations.length; i++) {
64-
var declaration = rule.declarations[i]
65-
if (declaration.property === 'transition') {
66-
var match = declaration.value.match(CHUNK_REGEXP)
67-
/* istanbul ignore else */
68-
if (match) {
69-
rule.declarations.splice(i, 1)
70-
match[4] && rule.declarations.push(i, 0, {type: 'declaration', property: 'transition-delay', value: match[4], position: declaration.position})
71-
match[3] && rule.declarations.push(i, 0, {type: 'declaration', property: 'transition-timing-function', value: match[3], position: declaration.position})
72-
match[2] && rule.declarations.push(i, 0, {type: 'declaration', property: 'transition-duration', value: match[2], position: declaration.position})
73-
match[1] && rule.declarations.push(i, 0, {type: 'declaration', property: 'transition-property', value: match[1], position: declaration.position})
74-
break
75-
}
76-
}
77-
}
78-
62+
rule.declarations = shorthandParser(rule.declarations)
7963
// padding & margin shorthand parsing
8064
convertLengthShorthand(rule, 'padding')
8165
convertLengthShorthand(rule, 'margin')

lib/shorthand-parser.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
function generateDeclaration (property, value, position) {
2+
return {
3+
type: 'declaration',
4+
property,
5+
value,
6+
position
7+
}
8+
}
9+
function transition (declaration) {
10+
let CHUNK_REGEXP = /^(\S*)?\s*(\d*\.?\d+(?:ms|s)?)?\s*(\S*)?\s*(\d*\.?\d+(?:ms|s)?)?$/
11+
const match = declaration.value.match(CHUNK_REGEXP)
12+
let result = []
13+
const position = declaration.position
14+
match[1] && result.push(generateDeclaration('transition-property', match[1], position))
15+
match[2] && result.push(generateDeclaration('transition-duration', match[2], position))
16+
match[3] && result.push(generateDeclaration('transition-timing-function', match[3], position))
17+
match[4] && result.push(generateDeclaration('transition-delay', match[4], position))
18+
return result
19+
}
20+
21+
function margin (declaration) {
22+
const position = declaration.position
23+
const splitResult = declaration.value.split(/\s+/)
24+
let result = []
25+
switch (splitResult.length) {
26+
case 1:
27+
splitResult.push(splitResult[0], splitResult[0], splitResult[0])
28+
break
29+
case 2:
30+
splitResult.push(splitResult[0], splitResult[1])
31+
break
32+
case 3:
33+
splitResult.push(splitResult[1])
34+
break
35+
}
36+
result.push(
37+
generateDeclaration('margin-top', splitResult[0], position),
38+
generateDeclaration('margin-right', splitResult[1], position),
39+
generateDeclaration('margin-bottom', splitResult[2], position),
40+
generateDeclaration('margin-left', splitResult[3], position)
41+
)
42+
return result
43+
}
44+
45+
const parserCollection = {
46+
transition,
47+
margin
48+
}
49+
50+
module.exports = function (declarations) {
51+
return declarations.reduce((result, declaration) => {
52+
const parser = parserCollection[declaration.property]
53+
if (parser) {
54+
return result.concat(parser(declaration))
55+
} else {
56+
result.push(declaration)
57+
return result
58+
}
59+
}, [])
60+
}

test/shorthand-parser.spec.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
var chai = require('chai')
2+
var sinon = require('sinon')
3+
var sinonChai = require('sinon-chai')
4+
var expect = chai.expect
5+
chai.use(sinonChai)
6+
7+
var shorthandParser = require('../lib/shorthand-parser')
8+
9+
describe('shorthand-parser', function () {
10+
it('parse transition', function () {
11+
const declarations = [
12+
{
13+
type: 'declaration',
14+
property: 'transition',
15+
value: 'margin-top 500ms ease-in-out 1s',
16+
position: {}
17+
}
18+
]
19+
const result = shorthandParser(declarations)
20+
expect(result).eql([
21+
{
22+
type: 'declaration',
23+
property: 'transition-property',
24+
value: 'margin-top',
25+
position: {}
26+
},
27+
{
28+
type: 'declaration',
29+
property: 'transition-duration',
30+
value: '500ms',
31+
position: {}
32+
},
33+
{
34+
type: 'declaration',
35+
property: 'transition-timing-function',
36+
value: 'ease-in-out',
37+
position: {}
38+
},
39+
{
40+
type: 'declaration',
41+
property: 'transition-delay',
42+
value: '1s',
43+
position: {}
44+
}
45+
])
46+
})
47+
48+
it('parse margin', function () {
49+
const declarations = [
50+
{
51+
type: 'declaration',
52+
property: 'margin',
53+
value: '1px',
54+
position: {}
55+
},
56+
{
57+
type: 'declaration',
58+
property: 'margin',
59+
value: '21px 22px',
60+
position: {}
61+
},
62+
{
63+
type: 'declaration',
64+
property: 'margin',
65+
value: '31px 32px 33px',
66+
position: {}
67+
},
68+
{
69+
type: 'declaration',
70+
property: 'margin',
71+
value: '41px 42px 43px 44px',
72+
position: {}
73+
}
74+
]
75+
const result = shorthandParser(declarations)
76+
expect(result).eql([
77+
{
78+
type: 'declaration',
79+
property: 'margin-top',
80+
value: '1px',
81+
position: {}
82+
},
83+
{
84+
type: 'declaration',
85+
property: 'margin-right',
86+
value: '1px',
87+
position: {}
88+
},
89+
{
90+
type: 'declaration',
91+
property: 'margin-bottom',
92+
value: '1px',
93+
position: {}
94+
},
95+
{
96+
type: 'declaration',
97+
property: 'margin-left',
98+
value: '1px',
99+
position: {}
100+
},
101+
102+
{
103+
type: 'declaration',
104+
property: 'margin-top',
105+
value: '21px',
106+
position: {}
107+
},
108+
{
109+
type: 'declaration',
110+
property: 'margin-right',
111+
value: '22px',
112+
position: {}
113+
},
114+
{
115+
type: 'declaration',
116+
property: 'margin-bottom',
117+
value: '21px',
118+
position: {}
119+
},
120+
{
121+
type: 'declaration',
122+
property: 'margin-left',
123+
value: '22px',
124+
position: {}
125+
},
126+
127+
{
128+
type: 'declaration',
129+
property: 'margin-top',
130+
value: '31px',
131+
position: {}
132+
},
133+
{
134+
type: 'declaration',
135+
property: 'margin-right',
136+
value: '32px',
137+
position: {}
138+
},
139+
{
140+
type: 'declaration',
141+
property: 'margin-bottom',
142+
value: '33px',
143+
position: {}
144+
},
145+
{
146+
type: 'declaration',
147+
property: 'margin-left',
148+
value: '32px',
149+
position: {}
150+
},
151+
152+
{
153+
type: 'declaration',
154+
property: 'margin-top',
155+
value: '41px',
156+
position: {}
157+
},
158+
{
159+
type: 'declaration',
160+
property: 'margin-right',
161+
value: '42px',
162+
position: {}
163+
},
164+
{
165+
type: 'declaration',
166+
property: 'margin-bottom',
167+
value: '43px',
168+
position: {}
169+
},
170+
{
171+
type: 'declaration',
172+
property: 'margin-left',
173+
value: '44px',
174+
position: {}
175+
}
176+
])
177+
})
178+
})

0 commit comments

Comments
 (0)