@@ -18,12 +18,14 @@ var defaults = {
1818 mediaQuery : false ,
1919 replace : true ,
2020 landscape : false ,
21- landscapeUnit : 'vh'
21+ landscapeUnit : 'vw' ,
22+ landscapeWidth : 568
2223} ;
2324
2425module . exports = postcss . plugin ( 'postcss-px-to-viewport' , function ( options ) {
2526
2627 var opts = objectAssign ( { } , defaults , options ) ;
28+
2729 var pxRegex = getUnitRegexp ( opts . unitToConvert ) ;
2830 var satisfyPropList = createPropListMatcher ( opts . propList ) ;
2931 var landscapeRules = [ ] ;
@@ -32,42 +34,63 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
3234 css . walkRules ( function ( rule ) {
3335 // Add exclude option to ignore some files like 'node_modules'
3436 var file = rule . source . input . file ;
35-
37+
3638 if ( opts . exclude && file ) {
3739 if ( Object . prototype . toString . call ( opts . exclude ) === '[object RegExp]' ) {
38- if ( ! handleExclude ( opts . exclude , file ) ) return ;
40+ if ( isExclude ( opts . exclude , file ) ) return ;
3941 } else if ( Object . prototype . toString . call ( opts . exclude ) === '[object Array]' ) {
4042 for ( let i = 0 ; i < opts . exclude . length ; i ++ ) {
41- if ( ! handleExclude ( opts . exclude [ i ] , file ) ) return ;
43+ if ( isExclude ( opts . exclude [ i ] , file ) ) return ;
4244 }
4345 } else {
4446 throw new Error ( 'options.exclude should be RegExp or Array.' ) ;
4547 }
4648 }
4749
48- if ( ! validateParams ( rule . parent . params , opts . mediaQuery ) ) return ;
4950 if ( blacklistedSelector ( opts . selectorBlackList , rule . selector ) ) return ;
50-
51+
5152 if ( opts . landscape && ! rule . parent . params ) {
5253 var landscapeRule = rule . clone ( ) . removeAll ( ) ;
53- landscapeRules . push ( landscapeRule ) ;
54-
54+
5555 rule . walkDecls ( function ( decl ) {
5656 if ( decl . value . indexOf ( opts . unitToConvert ) === - 1 ) return ;
5757 if ( ! satisfyPropList ( decl . prop ) ) return ;
5858
59- landscapeRule . append ( decl . clone ( {
60- value : decl . value . replace ( pxRegex , createPxReplace ( opts , opts . landscapeUnit ) )
61- } ) ) ;
59+ var landscapeDecl = decl . clone ( {
60+ value : decl . value . replace ( pxRegex , createPxReplace ( opts , opts . landscapeUnit , opts . landscapeWidth ) )
61+ } ) ;
62+
63+ if ( opts . replace ) {
64+ landscapeRule . append ( landscapeDecl ) ;
65+ } else {
66+ landscapeRule . append ( [ decl . clone ( ) , landscapeDecl ] ) ;
67+ }
6268 } ) ;
69+
70+ if ( landscapeRule . nodes . length > 0 ) {
71+ landscapeRules . push ( landscapeRule ) ;
72+ }
6373 }
74+
75+ if ( ! validateParams ( rule . parent . params , opts . mediaQuery ) ) return ;
6476
6577 rule . walkDecls ( function ( decl , i ) {
6678 if ( decl . value . indexOf ( opts . unitToConvert ) === - 1 ) return ;
6779 if ( ! satisfyPropList ( decl . prop ) ) return ;
6880
69- var unit = getUnit ( decl . prop , opts ) ;
70- var value = decl . value . replace ( pxRegex , createPxReplace ( opts , unit ) ) ;
81+ var unit ;
82+ var size ;
83+ var params = rule . parent . params ;
84+
85+ if ( opts . landscape && params && params . indexOf ( 'landscape' ) !== - 1 ) {
86+ unit = opts . landscapeUnit ;
87+ size = opts . landscapeWidth ;
88+ } else {
89+ unit = getUnit ( decl . prop , opts ) ;
90+ size = opts . viewportWidth ;
91+ }
92+
93+ var value = decl . value . replace ( pxRegex , createPxReplace ( opts , unit , size ) ) ;
7194
7295 if ( declarationExists ( decl . parent , decl . prop , value ) ) return ;
7396
@@ -82,29 +105,24 @@ module.exports = postcss.plugin('postcss-px-to-viewport', function (options) {
82105 if ( landscapeRules . length > 0 ) {
83106 var landscapeRoot = new postcss . atRule ( { params : '(orientation: landscape)' , name : 'media' } ) ;
84107
85- landscapeRules . forEach ( rule => landscapeRoot . append ( rule ) ) ;
108+ landscapeRules . forEach ( function ( rule ) {
109+ landscapeRoot . append ( rule ) ;
110+ } ) ;
86111 css . append ( landscapeRoot ) ;
87112 }
88113 } ;
89114} ) ;
90115
91- function handleExclude ( reg , file ) {
92- if ( Object . prototype . toString . call ( reg ) !== '[object RegExp]' ) {
93- throw new Error ( 'options.exclude should be RegExp.' ) ;
94- }
95- return file . match ( reg ) === null ;
96- }
97-
98116function getUnit ( prop , opts ) {
99117 return prop . indexOf ( 'font' ) === - 1 ? opts . viewportUnit : opts . fontViewportUnit ;
100118}
101119
102- function createPxReplace ( opts , viewportUnit ) {
120+ function createPxReplace ( opts , viewportUnit , viewportSize ) {
103121 return function ( m , $1 ) {
104122 if ( ! $1 ) return m ;
105123 var pixels = parseFloat ( $1 ) ;
106124 if ( pixels <= opts . minPixelValue ) return m ;
107- var parsedVal = toFixed ( ( pixels / opts . viewportWidth * 100 ) , opts . unitPrecision ) ;
125+ var parsedVal = toFixed ( ( pixels / viewportSize * 100 ) , opts . unitPrecision ) ;
108126 return parsedVal === 0 ? '0' : parsedVal + viewportUnit ;
109127 } ;
110128}
@@ -123,12 +141,19 @@ function blacklistedSelector(blacklist, selector) {
123141 } ) ;
124142}
125143
144+ function isExclude ( reg , file ) {
145+ if ( Object . prototype . toString . call ( reg ) !== '[object RegExp]' ) {
146+ throw new Error ( 'options.exclude should be RegExp.' ) ;
147+ }
148+ return file . match ( reg ) !== null ;
149+ }
150+
126151function declarationExists ( decls , prop , value ) {
127152 return decls . some ( function ( decl ) {
128153 return ( decl . prop === prop && decl . value === value ) ;
129154 } ) ;
130155}
131156
132157function validateParams ( params , mediaQuery ) {
133- return ! params || ( params && mediaQuery && params . indexOf ( 'landscape' ) === - 1 ) ;
158+ return ! params || ( params && mediaQuery ) ;
134159}
0 commit comments