@@ -5,135 +5,161 @@ const colorObject = require('color-name');
55const parserColor = require ( 'parse-color' ) ;
66const nearestColor = require ( 'nearest-color' ) ;
77
8- module . exports = postcss . plugin ( 'postcss-extract-value' , ( opts ) => {
9- // Fix for Node 4
10- const params = opts || { } ;
8+ const colorList = { } ;
119
12- // Options
13- const filterByProps = params . filterByProps ;
14- const onlyColor = params . onlyColor ;
15- const scope = params . scope || ':root' ;
16- const templateVariableName = params . templateVariableName || '' ;
10+ Object . keys ( colorObject ) . forEach ( ( key ) => {
11+ colorList [ key ] = {
12+ r : colorObject [ key ] [ 0 ] ,
13+ g : colorObject [ key ] [ 1 ] ,
14+ b : colorObject [ key ] [ 2 ] ,
15+ } ;
16+ } ) ;
17+ const findColor = nearestColor . from ( colorList ) ;
1718
19+ function checkProp ( filter , prop ) {
20+ return filter . indexOf ( prop ) > - 1 ;
21+ }
1822
19- const colorList = { } ;
20- const colorNameList = Object . keys ( colorObject ) ;
23+ function isColor ( reColorKeywords , value ) {
24+ const reCheck = new RegExp ( `${ / # \w + | r g b a ? | h s l a ? / . source } |${ reColorKeywords . source } ` , 'g' ) ;
25+ return reCheck . test ( value ) ;
26+ }
2127
22- colorNameList . forEach ( ( key ) => {
23- colorList [ key ] = {
24- r : colorObject [ key ] [ 0 ] ,
25- g : colorObject [ key ] [ 1 ] ,
26- b : colorObject [ key ] [ 2 ] ,
27- } ;
28- } ) ;
29- const findColor = nearestColor . from ( colorList ) ;
30- const variablesListCounter = { } ;
28+ function extractColor ( reExtract , value ) {
29+ const resultArray = [ ] ;
30+ let result = reExtract . exec ( value ) ;
3131
32- // Cache RegExp
33- const reColorKeywords = new RegExp ( colorNameList . join ( '|' ) ) ;
34- const reCSSVariable = / ^ v a r \( - { 2 } \w { 1 } [ \w + - ] * / ;
35- const reHex = / # ( \w { 6 } | \w { 3 } ) / ;
36- const reRgb = / r g b a ? \( [ \d , . \s ] + \) / ;
37- const reHsl = / h s l a ? \( \s ? [ 0 - 9 ] { 1 , 3 } , \s ? ( [ 0 - 9 ] { 1 , 3 } % , ? \s ? ) { 2 } ( [ 0 - 9 . ] + ) ? \) / ;
38- const reExtract = new RegExp ( `${ reHex . source } |${ reRgb . source } |${ reHsl . source } |${ reColorKeywords . source } ` , 'g' ) ;
39-
40- function isColor ( value ) {
41- const reCheck = new RegExp ( `${ / # \w + | r g b a ? | h s l a ? / . source } |${ reColorKeywords . source } ` , 'g' ) ;
42- return reCheck . test ( value ) ;
32+ while ( result ) {
33+ resultArray . push ( result [ 0 ] ) ;
34+ result = reExtract . exec ( value ) ;
4335 }
36+ return resultArray ;
37+ }
4438
45- function extractColor ( value ) {
46- const resultArray = [ ] ;
47- let result = reExtract . exec ( value ) ;
39+ function colorNameVariable ( templateVariableName , value ) {
40+ const variable = { } ;
41+ let nearestColorValue = { } ;
42+ const parsedColor = parserColor ( value ) ;
4843
49- while ( result ) {
50- resultArray . push ( result [ 0 ] ) ;
51- result = reExtract . exec ( value ) ;
52- }
53- return resultArray ;
44+ if ( parsedColor . hex ) {
45+ nearestColorValue = parserColor ( findColor ( parsedColor . hex ) . value ) ;
5446 }
5547
56- function checkProp ( filter , prop ) {
57- return filter . indexOf ( prop ) > - 1 ;
58- }
48+ if ( nearestColorValue ) {
49+ variable . colorKeyword = nearestColorValue . keyword ;
5950
60- function colorNameVariable ( value ) {
61- const variable = { } ;
62- let nearestColorValue = { } ;
63- const parsedColor = parserColor ( value ) ;
64-
65- if ( parsedColor . hex ) {
66- nearestColorValue = parserColor ( findColor ( parsedColor . hex ) . value ) ;
67- }
68-
69- if ( nearestColorValue ) {
70- variable . colorKeyword = nearestColorValue . keyword ;
71-
72- if ( templateVariableName . indexOf ( '[tint]' ) > - 1 ) {
73- if ( nearestColorValue . hsl [ 2 ] > parsedColor . hsl [ 2 ] ) {
74- variable . tint = 'dark' ;
75- } else if ( nearestColorValue . hsl [ 2 ] < parsedColor . hsl [ 2 ] ) {
76- variable . tint = 'light' ;
77- } else {
78- variable . tint = '' ;
79- }
51+ if ( templateVariableName . indexOf ( '[tint]' ) > - 1 ) {
52+ if ( nearestColorValue . hsl [ 2 ] > parsedColor . hsl [ 2 ] ) {
53+ variable . tint = 'dark' ;
54+ } else if ( nearestColorValue . hsl [ 2 ] < parsedColor . hsl [ 2 ] ) {
55+ variable . tint = 'light' ;
56+ } else {
57+ variable . tint = '' ;
58+ }
8059
81- if ( variable . tint ) {
82- if ( templateVariableName . indexOf ( '[tint]' ) > 0 ) {
83- variable . tint = `-${ variable . tint } ` ;
84- }
60+ if ( variable . tint ) {
61+ if ( templateVariableName . indexOf ( '[tint]' ) > 0 ) {
62+ variable . tint = `-${ variable . tint } ` ;
8563 }
8664 }
87- if ( templateVariableName . indexOf ( '[colorKeyword]' ) > 0 &&
88- ! ( templateVariableName . indexOf ( '[tint]' ) === 0 &&
89- ! variable . tint ) ) {
90- variable . colorKeyword = `-${ variable . colorKeyword } ` ;
91- }
9265 }
93-
94- return variable ;
66+ if ( templateVariableName . indexOf ( '[colorKeyword]' ) > 0 &&
67+ ! ( templateVariableName . indexOf ( '[tint]' ) === 0 &&
68+ ! variable . tint ) ) {
69+ variable . colorKeyword = `-${ variable . colorKeyword } ` ;
70+ }
9571 }
9672
97- function makeNameByTemplate ( value , prop ) {
98- let nameVariables = [ ] ;
99- let result = templateVariableName ;
73+ return variable ;
74+ }
10075
101- if ( onlyColor ) {
102- nameVariables = colorNameVariable ( value ) ;
103- } else if ( templateVariableName . indexOf ( '[propertyName]' ) ) {
104- nameVariables . propertyName = prop ;
105- }
106- Object . keys ( nameVariables ) . forEach ( ( key ) => {
107- result = result . replace ( `[${ key } ]` , nameVariables [ key ] ) ;
108- } ) ;
109- return result ;
76+ function makeNameByTemplate ( templateVariableName , onlyColor , value , prop ) {
77+ let nameVariables = [ ] ;
78+ let result = templateVariableName ;
79+
80+ if ( onlyColor ) {
81+ nameVariables = colorNameVariable ( templateVariableName , value ) ;
82+ } else if ( templateVariableName . indexOf ( '[propertyName]' ) ) {
83+ nameVariables . propertyName = prop ;
11084 }
85+ Object . keys ( nameVariables ) . forEach ( ( key ) => {
86+ result = result . replace ( `[${ key } ]` , nameVariables [ key ] ) ;
87+ } ) ;
88+ return result ;
89+ }
11190
112- function makeCSSVariable ( prop , num , value ) {
113- let variableName = '' ;
114- let result = '' ;
91+ function addVariablePrefix ( variablePrefix , variableSyntax , variable ) {
92+ const prefix = variablePrefix [ variableSyntax ] ;
93+ return `${ prefix || variablePrefix . default } ${ variable } ` ;
94+ }
11595
116- if ( templateVariableName ) {
117- variableName = makeNameByTemplate ( value , prop ) ;
118- result = variableName ;
96+ function makeCSSVariable ( templateVariableName , variablePrefix , variableSyntax , onlyColor ,
97+ variablesListCounter , prop , num , value ) {
98+ let variableName = '' ;
99+ let result = '' ;
119100
120- if ( ! variablesListCounter [ variableName ] ) {
121- variablesListCounter [ variableName ] = 1 ;
122- }
101+ if ( templateVariableName ) {
102+ variableName = makeNameByTemplate ( templateVariableName , onlyColor , value , prop ) ;
103+ result = variableName ;
123104
124- result += `-${ variablesListCounter [ variableName ] } ` ;
125- variablesListCounter [ variableName ] += 1 ;
126- } else {
127- variableName = `${ prop } -${ num } ` ;
128- result = variableName ;
105+ if ( ! variablesListCounter [ variableName ] ) {
106+ variablesListCounter [ variableName ] = 1 ;
129107 }
130108
131- return `--${ result } ` ;
109+ result += `-${ variablesListCounter [ variableName ] } ` ;
110+ variablesListCounter [ variableName ] += 1 ;
111+ } else {
112+ variableName = `${ prop } -${ num } ` ;
113+ result = variableName ;
132114 }
133115
134- function addCSSVariable ( currentScope , value , variableName ) {
116+ return addVariablePrefix ( variablePrefix , variableSyntax , result ) ;
117+ }
118+
119+ function addCSSVariable ( variableSyntax , currentScope , value , variableName ) {
120+ if ( variableSyntax ) {
121+ currentScope . prepend ( `${ variableName } : ${ value } ` ) ;
122+ } else {
135123 currentScope . append ( `${ variableName } : ${ value } ` ) ;
136124 }
125+ }
126+
127+ function hasVariable ( variableSyntax , reCSSVariable , value ) {
128+ const reTest = reCSSVariable [ variableSyntax ] || reCSSVariable . default ;
129+ return reTest . test ( value ) ;
130+ }
131+
132+ module . exports = postcss . plugin ( 'postcss-extract-value' , ( opts ) => {
133+ // Fix for Node 4
134+ const params = opts || { } ;
135+
136+ // Options
137+ const filterByProps = params . filterByProps ;
138+ const onlyColor = params . onlyColor ;
139+ const scope = params . scope || ':root' ;
140+ const templateVariableName = params . templateVariableName || '' ;
141+ const variableSyntax = params . variableSyntax || '' ;
142+
143+
144+ const variablePrefix = {
145+ default : '--' ,
146+ less : '@' ,
147+ sass : '$' ,
148+ } ;
149+
150+ const variablesListCounter = { } ;
151+
152+ // Cache RegExp
153+ const reColorKeywords = new RegExp ( colorNameList . join ( '|' ) ) ;
154+ const reCSSVariable = {
155+ default : / ^ v a r \( - { 2 } \w { 1 } [ \w + - ] * / ,
156+ sass : / \$ \w { 1 } [ \w + - ] * / ,
157+ less : / @ \w { 1 } [ \w + - ] * / ,
158+ } ;
159+ const reHex = / # ( \w { 6 } | \w { 3 } ) / ;
160+ const reRgb = / r g b a ? \( [ \d , . \s ] + \) / ;
161+ const reHsl = / h s l a ? \( \s ? [ 0 - 9 ] { 1 , 3 } , \s ? ( [ 0 - 9 ] { 1 , 3 } % , ? \s ? ) { 2 } ( [ 0 - 9 . ] + ) ? \) / ;
162+ const reExtract = new RegExp ( `${ reHex . source } |${ reRgb . source } |${ reHsl . source } |${ reColorKeywords . source } ` , 'g' ) ;
137163
138164 return function parser ( css ) {
139165 const root = css . root ( ) ;
@@ -151,8 +177,9 @@ module.exports = postcss.plugin('postcss-extract-value', (opts) => {
151177 rootSel = rule ;
152178 } else {
153179 rule . walkDecls ( ( decl ) => {
154- if ( ! reCSSVariable . test ( decl . value ) ) {
155- checkColorFilter = ! onlyColor || onlyColor && isColor ( decl . value ) ;
180+ if ( ! hasVariable ( variableSyntax , reCSSVariable , decl . value ) ) {
181+ checkColorFilter = ! onlyColor || onlyColor
182+ && isColor ( reColorKeywords , decl . value ) ;
156183
157184 checkPropFilter = ( ! filterByProps || filterByProps
158185 && checkProp ( filterByProps , decl . prop ) ) ;
@@ -163,7 +190,7 @@ module.exports = postcss.plugin('postcss-extract-value', (opts) => {
163190 }
164191
165192 if ( onlyColor ) {
166- filteredValueList = extractColor ( decl . value ) ;
193+ filteredValueList = extractColor ( reExtract , decl . value ) ;
167194 } else {
168195 filteredValueList = new Array ( decl . value ) ;
169196 }
@@ -178,11 +205,18 @@ module.exports = postcss.plugin('postcss-extract-value', (opts) => {
178205 variableName = variablesList [ filteredValue ] ;
179206 } else {
180207 positionValue = storeProps [ decl . prop ] . indexOf ( filteredValue ) + 1 ;
181- variableName = makeCSSVariable ( decl . prop , positionValue , filteredValue ) ;
208+ variableName = makeCSSVariable ( templateVariableName , variablePrefix ,
209+ variableSyntax , onlyColor , variablesListCounter , decl . prop , positionValue ,
210+ filteredValue ) ;
182211 variablesList [ filteredValue ] = variableName ;
183212 }
184- decl . value = decl . value . replace ( filteredValue ,
185- `var(${ variableName } )` ) ;
213+ if ( variableSyntax ) {
214+ decl . value = decl . value . replace ( filteredValue ,
215+ `${ variableName } ` ) ;
216+ } else {
217+ decl . value = decl . value . replace ( filteredValue ,
218+ `var(${ variableName } )` ) ;
219+ }
186220 } ) ;
187221 }
188222 }
@@ -191,12 +225,21 @@ module.exports = postcss.plugin('postcss-extract-value', (opts) => {
191225 } ) ;
192226
193227 if ( Object . keys ( rootSel ) . length === 0 ) {
194- rootSel = postcss . rule ( { selector : scope } ) ;
195- root . prepend ( rootSel ) ;
228+ if ( ! variableSyntax ) {
229+ rootSel = postcss . rule ( { selector : scope } ) ;
230+ root . prepend ( rootSel ) ;
231+ } else {
232+ rootSel = root ;
233+ }
234+ }
235+
236+ const varialbleListKeys = Object . keys ( variablesList ) ;
237+ if ( variableSyntax ) {
238+ varialbleListKeys . reverse ( ) ;
196239 }
197240
198- Object . keys ( variablesList ) . forEach ( ( value ) => {
199- addCSSVariable ( rootSel , value , variablesList [ value ] ) ;
241+ varialbleListKeys . forEach ( ( value ) => {
242+ addCSSVariable ( variableSyntax , rootSel , value , variablesList [ value ] ) ;
200243 } ) ;
201244 } ;
202245} ) ;
0 commit comments