postcss-pxtransform 3.3.14 → 3.5.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,20 +1,21 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
- Copyright 2018 Pines-Cheng <spider.cs.nuc@gmail.com>
3
+ Copyright (c) 2018
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
11
 
12
12
  The above copyright notice and this permission notice shall be included in all
13
13
  copies or substantial portions of the Software.
14
14
 
15
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,620 @@
1
+ // Jasmine unit tests
2
+ // To run tests, run these commands from the project root:
3
+ // 1. `npm install -g jasmine-node`
4
+ // 2. `jasmine-node spec`
5
+
6
+ /* global describe, it, expect */
7
+
8
+ 'use strict'
9
+ const postcss = require('postcss')
10
+ const pxtorem = require('../index')
11
+ const basicCSS = '.rule { font-size: 15px }'
12
+ const filterPropList = require('../lib/filter-prop-list')
13
+
14
+ describe('pxtorem', function () {
15
+ it('1 should work on the readme example', function () {
16
+ const input = 'h1 { margin: 0 0 20px; font-size: 32px; line-height: 1.2; letter-spacing: 1px; }'
17
+ const output = 'h1 { margin: 0 0 0.5rem; font-size: 0.8rem; line-height: 1.2; letter-spacing: 0.025rem; }'
18
+ const processed = postcss(pxtorem({ platform: 'h5', designWidth: 640 }))
19
+ .process(input).css
20
+
21
+ expect(processed).toBe(output)
22
+ })
23
+
24
+ it('2 should replace the px unit with rem', function () {
25
+ const processed = postcss(pxtorem({ platform: 'h5', designWidth: 640 }))
26
+ .process(basicCSS).css
27
+ const expected = '.rule { font-size: 0.375rem }'
28
+
29
+ expect(processed).toBe(expected)
30
+ })
31
+
32
+ it('3 should ignore non px properties', function () {
33
+ const expected = '.rule { font-size: 2em }'
34
+ const processed = postcss(pxtorem({ platform: 'h5', designWidth: 640 }))
35
+ .process(expected).css
36
+
37
+ expect(processed).toBe(expected)
38
+ })
39
+
40
+ it('4 should handle < 1 values and values without a leading 0 - legacy',
41
+ function () {
42
+ const rules = '.rule { margin: 0.5rem .5px -0.2px -.2em }'
43
+ const expected = '.rule { margin: 0.5rem 0.0125rem -0.005rem -.2em }'
44
+ const options = {
45
+ platform: 'h5',
46
+ designWidth: 640,
47
+ propWhiteList: ['margin']
48
+ }
49
+ const processed = postcss(pxtorem(options)).process(rules).css
50
+
51
+ expect(processed).toBe(expected)
52
+ })
53
+
54
+ it('5 should handle < 1 values and values without a leading 0', function () {
55
+ const rules = '.rule { margin: 0.5rem .5px -0.2px -.2em }'
56
+ const expected = '.rule { margin: 0.5rem 0.0125rem -0.005rem -.2em }'
57
+ const options = {
58
+ platform: 'h5',
59
+ designWidth: 640,
60
+ propList: ['margin']
61
+ }
62
+ const processed = postcss(pxtorem(options)).process(rules).css
63
+
64
+ expect(processed).toBe(expected)
65
+ })
66
+
67
+ it('6 should not add properties that already exist', function () {
68
+ const expected = '.rule { font-size: 40px; font-size: 1rem; }'
69
+ const processed = postcss(pxtorem({ platform: 'h5', designWidth: 640 }))
70
+ .process(expected).css
71
+
72
+ expect(processed).toBe(expected)
73
+ })
74
+
75
+ it('7 should remain unitless if 0', function () {
76
+ const expected = '.rule { font-size: 0px; font-size: 0; }'
77
+ const processed = postcss(pxtorem()).process(expected).css
78
+
79
+ expect(processed).toBe(expected)
80
+ })
81
+ })
82
+
83
+ describe('value parsing', function () {
84
+ it('1 should not replace values in double quotes or single quotes - legacy',
85
+ function () {
86
+ const options = {
87
+ platform: 'h5',
88
+ designWidth: 640
89
+ // propWhiteList: []
90
+ }
91
+ const rules = '.rule { content: \'16px\'; font-family: "16px"; font-size: 16px; }'
92
+ const expected = '.rule { content: \'16px\'; font-family: "16px"; font-size: 0.4rem; }'
93
+ const processed = postcss(pxtorem(options)).process(rules).css
94
+
95
+ expect(processed).toBe(expected)
96
+ })
97
+
98
+ it('2 should not replace values in double quotes or single quotes',
99
+ function () {
100
+ const options = {
101
+ platform: 'h5',
102
+ designWidth: 640,
103
+ propList: ['*']
104
+ }
105
+ const rules = '.rule { content: \'16px\'; font-family: "16px"; font-size: 16px; }'
106
+ const expected = '.rule { content: \'16px\'; font-family: "16px"; font-size: 0.4rem; }'
107
+ const processed = postcss(pxtorem(options)).process(rules).css
108
+
109
+ expect(processed).toBe(expected)
110
+ })
111
+
112
+ it('3 should not replace values in `url()` - legacy', function () {
113
+ const options = {
114
+ platform: 'h5',
115
+ designWidth: 640
116
+ // propWhiteList: []
117
+ }
118
+ const rules = '.rule { background: url(16px.jpg); font-size: 16px; }'
119
+ const expected = '.rule { background: url(16px.jpg); font-size: 0.4rem; }'
120
+ const processed = postcss(pxtorem(options)).process(rules).css
121
+
122
+ expect(processed).toBe(expected)
123
+ })
124
+
125
+ it('4 should not replace values in `url()`', function () {
126
+ const options = {
127
+ platform: 'h5',
128
+ designWidth: 640,
129
+ propList: ['*']
130
+ }
131
+ const rules = '.rule { background: url(16px.jpg); font-size: 16px; }'
132
+ const expected = '.rule { background: url(16px.jpg); font-size: 0.4rem; }'
133
+ const processed = postcss(pxtorem(options)).process(rules).css
134
+
135
+ expect(processed).toBe(expected)
136
+ })
137
+
138
+ it('5 should not replace values with an uppercase P or X', function () {
139
+ const options = {
140
+ platform: 'h5',
141
+ designWidth: 640,
142
+ propList: ['*']
143
+ }
144
+ const rules = '.rule { margin: 12px calc(100% - 14PX); height: calc(100% - 20px); font-size: 12Px; line-height: 16px; }'
145
+ const expected = '.rule { margin: 0.3rem calc(100% - 14PX); height: calc(100% - 0.5rem); font-size: 12Px; line-height: 0.4rem; }'
146
+ const processed = postcss(pxtorem(options)).process(rules).css
147
+
148
+ expect(processed).toBe(expected)
149
+ })
150
+ })
151
+
152
+ describe('unitPrecision', function () {
153
+ // Deprecate
154
+ it('1 should replace using a decimal of 2 places - legacy', function () {
155
+ const expected = '.rule { font-size: 0.38rem }'
156
+ const options = {
157
+ platform: 'h5',
158
+ designWidth: 640,
159
+ unit_precision: 2
160
+ }
161
+ const processed = postcss(pxtorem(options)).process(basicCSS).css
162
+
163
+ expect(processed).toBe(expected)
164
+ })
165
+
166
+ it('2 should replace using a decimal of 2 places', function () {
167
+ const expected = '.rule { font-size: 0.38rem }'
168
+ const options = {
169
+ platform: 'h5',
170
+ designWidth: 640,
171
+ unitPrecision: 2
172
+ }
173
+ const processed = postcss(pxtorem(options)).process(basicCSS).css
174
+
175
+ expect(processed).toBe(expected)
176
+ })
177
+ })
178
+
179
+ describe('propWhiteList', function () {
180
+ // Deprecate
181
+ it('3 should only replace properties in the white list - legacy',
182
+ function () {
183
+ const expected = '.rule { font-size: 15px }'
184
+ const options = {
185
+ platform: 'h5',
186
+ designWidth: 640,
187
+ prop_white_list: ['font']
188
+ }
189
+ const processed = postcss(pxtorem(options)).process(basicCSS).css
190
+
191
+ expect(processed).toBe(expected)
192
+ })
193
+
194
+ it('4 should only replace properties in the white list - legacy',
195
+ function () {
196
+ const expected = '.rule { font-size: 15px }'
197
+ const options = {
198
+ platform: 'h5',
199
+ designWidth: 640,
200
+ propWhiteList: ['font']
201
+ }
202
+ const processed = postcss(pxtorem(options)).process(basicCSS).css
203
+
204
+ expect(processed).toBe(expected)
205
+ })
206
+
207
+ it('5 should only replace properties in the white list - legacy',
208
+ function () {
209
+ const css = '.rule { margin: 16px; margin-left: 10px }'
210
+ const expected = '.rule { margin: 0.4rem; margin-left: 10px }'
211
+ const options = {
212
+ platform: 'h5',
213
+ designWidth: 640,
214
+ propWhiteList: ['margin']
215
+ }
216
+ const processed = postcss(pxtorem(options)).process(css).css
217
+
218
+ expect(processed).toBe(expected)
219
+ })
220
+
221
+ it('6 should only replace properties in the prop list', function () {
222
+ const css = '.rule { font-size: 16px; margin: 16px; margin-left: 5px; padding: 5px; padding-right: 16px }'
223
+ const expected = '.rule { font-size: 0.4rem; margin: 0.4rem; margin-left: 5px; padding: 5px; padding-right: 0.4rem }'
224
+ const options = {
225
+ platform: 'h5',
226
+ designWidth: 640,
227
+ propWhiteList: ['*font*', 'margin*', '!margin-left', '*-right', 'pad']
228
+ }
229
+ const processed = postcss(pxtorem(options)).process(css).css
230
+
231
+ expect(processed).toBe(expected)
232
+ })
233
+
234
+ it('7 should only replace properties in the prop list with wildcard',
235
+ function () {
236
+ const css = '.rule { font-size: 16px; margin: 16px; margin-left: 5px; padding: 5px; padding-right: 16px }'
237
+ const expected = '.rule { font-size: 16px; margin: 0.4rem; margin-left: 5px; padding: 5px; padding-right: 16px }'
238
+ const options = {
239
+ platform: 'h5',
240
+ designWidth: 640,
241
+ propWhiteList: ['*', '!margin-left', '!*padding*', '!font*']
242
+ }
243
+ const processed = postcss(pxtorem(options)).process(css).css
244
+
245
+ expect(processed).toBe(expected)
246
+ })
247
+
248
+ it('8 should replace all properties when white list is empty', function () {
249
+ const rules = '.rule { margin: 16px; font-size: 15px }'
250
+ const expected = '.rule { margin: 0.4rem; font-size: 0.375rem }'
251
+ const options = {
252
+ platform: 'h5',
253
+ designWidth: 640
254
+ // propWhiteList: []
255
+ }
256
+ const processed = postcss(pxtorem(options)).process(rules).css
257
+
258
+ expect(processed).toBe(expected)
259
+ })
260
+ })
261
+
262
+ describe('selectorBlackList', function () {
263
+ // Deprecate
264
+ it('1 should ignore selectors in the selector black list - legacy',
265
+ function () {
266
+ const rules = '.rule { font-size: 15px } .rule2 { font-size: 15px }'
267
+ const expected = '.rule { font-size: 0.375rem } .rule2 { font-size: 15px }'
268
+ const options = {
269
+ platform: 'h5',
270
+ designWidth: 640,
271
+ selector_black_list: ['.rule2']
272
+ }
273
+ const processed = postcss(pxtorem(options)).process(rules).css
274
+
275
+ expect(processed).toBe(expected)
276
+ })
277
+
278
+ it('2 should ignore selectors in the selector black list', function () {
279
+ const rules = '.rule { font-size: 15px } .rule2 { font-size: 15px }'
280
+ const expected = '.rule { font-size: 0.375rem } .rule2 { font-size: 15px }'
281
+ const options = {
282
+ platform: 'h5',
283
+ designWidth: 640,
284
+ selectorBlackList: ['.rule2']
285
+ }
286
+ const processed = postcss(pxtorem(options)).process(rules).css
287
+
288
+ expect(processed).toBe(expected)
289
+ })
290
+
291
+ it('3 should ignore every selector with `body$`', function () {
292
+ const rules = 'body { font-size: 16px; } .class-body$ { font-size: 16px; } .simple-class { font-size: 16px; }'
293
+ const expected = 'body { font-size: 0.4rem; } .class-body$ { font-size: 16px; } .simple-class { font-size: 0.4rem; }'
294
+ const options = {
295
+ platform: 'h5',
296
+ designWidth: 640,
297
+ selectorBlackList: ['body$']
298
+ }
299
+ const processed = postcss(pxtorem(options)).process(rules).css
300
+
301
+ expect(processed).toBe(expected)
302
+ })
303
+
304
+ it('4 should only ignore exactly `body`', function () {
305
+ const rules = 'body { font-size: 16px; } .class-body { font-size: 16px; } .simple-class { font-size: 16px; }'
306
+ const expected = 'body { font-size: 16px; } .class-body { font-size: 0.4rem; } .simple-class { font-size: 0.4rem; }'
307
+ const options = {
308
+ platform: 'h5',
309
+ designWidth: 640,
310
+ selectorBlackList: [/^body$/]
311
+ }
312
+ const processed = postcss(pxtorem(options)).process(rules).css
313
+
314
+ expect(processed).toBe(expected)
315
+ })
316
+ })
317
+
318
+ describe('replace', function () {
319
+ it('1 should leave fallback pixel unit with root em value', function () {
320
+ const options = {
321
+ platform: 'h5',
322
+ designWidth: 640,
323
+ replace: false
324
+ }
325
+ const processed = postcss(pxtorem(options)).process(basicCSS).css
326
+ const expected = '.rule { font-size: 15px; font-size: 0.375rem }'
327
+
328
+ expect(processed).toBe(expected)
329
+ })
330
+ })
331
+
332
+ describe('mediaQuery', function () {
333
+ // Deprecate
334
+ it('1 should replace px in media queries', function () {
335
+ const options = {
336
+ platform: 'h5',
337
+ designWidth: 640,
338
+ media_query: true
339
+ }
340
+ const processed = postcss(pxtorem(options))
341
+ .process('@media (min-width: 500px) { .rule { font-size: 16px } }').css
342
+ const expected = '@media (min-width: 12.5rem) { .rule { font-size: 0.4rem } }'
343
+
344
+ expect(processed).toBe(expected)
345
+ })
346
+
347
+ it('2 should replace px in media queries', function () {
348
+ const options = {
349
+ platform: 'h5',
350
+ designWidth: 640,
351
+ mediaQuery: true
352
+ }
353
+ const processed = postcss(pxtorem(options))
354
+ .process('@media (min-width: 500px) { .rule { font-size: 16px } }').css
355
+ const expected = '@media (min-width: 12.5rem) { .rule { font-size: 0.4rem } }'
356
+
357
+ expect(processed).toBe(expected)
358
+ })
359
+ })
360
+
361
+ describe('minPixelValue', function () {
362
+ it('1 should not replace values below minPixelValue', function () {
363
+ const options = {
364
+ platform: 'h5',
365
+ designWidth: 640,
366
+ // propWhiteList: [],
367
+ minPixelValue: 2
368
+ }
369
+ const rules = '.rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }'
370
+ const expected = '.rule { border: 1px solid #000; font-size: 0.4rem; margin: 1px 0.25rem; }'
371
+ const processed = postcss(pxtorem(options)).process(rules).css
372
+
373
+ expect(processed).toBe(expected)
374
+ })
375
+ })
376
+
377
+ describe('filter-prop-list', function () {
378
+ it('1 should find "exact" matches from propList', function () {
379
+ const propList = [
380
+ 'font-size',
381
+ 'margin',
382
+ '!padding',
383
+ '*border*',
384
+ '*',
385
+ '*y',
386
+ '!*font*']
387
+ const expected = 'font-size,margin'
388
+ expect(filterPropList.exact(propList).join()).toBe(expected)
389
+ })
390
+
391
+ it('2 should find "contain" matches from propList and reduce to string',
392
+ function () {
393
+ const propList = [
394
+ 'font-size',
395
+ '*margin*',
396
+ '!padding',
397
+ '*border*',
398
+ '*',
399
+ '*y',
400
+ '!*font*']
401
+ const expected = 'margin,border'
402
+ expect(filterPropList.contain(propList).join()).toBe(expected)
403
+ })
404
+
405
+ it('3 should find "start" matches from propList and reduce to string',
406
+ function () {
407
+ const propList = [
408
+ 'font-size',
409
+ '*margin*',
410
+ '!padding',
411
+ 'border*',
412
+ '*',
413
+ '*y',
414
+ '!*font*']
415
+ const expected = 'border'
416
+ expect(filterPropList.startWith(propList).join()).toBe(expected)
417
+ })
418
+
419
+ it('4 should find "end" matches from propList and reduce to string',
420
+ function () {
421
+ const propList = [
422
+ 'font-size',
423
+ '*margin*',
424
+ '!padding',
425
+ 'border*',
426
+ '*',
427
+ '*y',
428
+ '!*font*']
429
+ const expected = 'y'
430
+ expect(filterPropList.endWith(propList).join()).toBe(expected)
431
+ })
432
+
433
+ it('5 should find "not" matches from propList and reduce to string',
434
+ function () {
435
+ const propList = [
436
+ 'font-size',
437
+ '*margin*',
438
+ '!padding',
439
+ 'border*',
440
+ '*',
441
+ '*y',
442
+ '!*font*']
443
+ const expected = 'padding'
444
+ expect(filterPropList.notExact(propList).join()).toBe(expected)
445
+ })
446
+
447
+ it('6 should find "not contain" matches from propList and reduce to string',
448
+ function () {
449
+ const propList = [
450
+ 'font-size',
451
+ '*margin*',
452
+ '!padding',
453
+ '!border*',
454
+ '*',
455
+ '*y',
456
+ '!*font*']
457
+ const expected = 'font'
458
+ expect(filterPropList.notContain(propList).join()).toBe(expected)
459
+ })
460
+
461
+ it('7 should find "not start" matches from propList and reduce to string',
462
+ function () {
463
+ const propList = [
464
+ 'font-size',
465
+ '*margin*',
466
+ '!padding',
467
+ '!border*',
468
+ '*',
469
+ '*y',
470
+ '!*font*']
471
+ const expected = 'border'
472
+ expect(filterPropList.notStartWith(propList).join()).toBe(expected)
473
+ })
474
+
475
+ it('8 should find "not end" matches from propList and reduce to string',
476
+ function () {
477
+ const propList = [
478
+ 'font-size',
479
+ '*margin*',
480
+ '!padding',
481
+ '!border*',
482
+ '*',
483
+ '!*y',
484
+ '!*font*']
485
+ const expected = 'y'
486
+ expect(filterPropList.notEndWith(propList).join()).toBe(expected)
487
+ })
488
+ })
489
+
490
+ // 补充的测试用例
491
+
492
+ describe('不传任何配置', () => {
493
+ it('不传任何配置', function () {
494
+ const rules = 'h1 {margin: 0 0 20px;font-size: 40px;line-height: 1.2;}'
495
+ const expected = 'h1 {margin: 0 0 20rpx;font-size: 40rpx;line-height: 1.2;}'
496
+ const processed = postcss(pxtorem()).process(rules).css
497
+
498
+ expect(processed).toBe(expected)
499
+ })
500
+ })
501
+
502
+ describe('platform 为 weapp', () => {
503
+ it('{platform: \'weapp\', designWidth: 750} ', () => {
504
+ const rules = 'h1 {margin: 0 0 20px;font-size: 40Px;line-height: 1.2;}'
505
+ const expected = 'h1 {margin: 0 0 20rpx;font-size: 40Px;line-height: 1.2;}'
506
+ const options = {
507
+ platform: 'weapp',
508
+ designWidth: 750
509
+ }
510
+ const processed = postcss(pxtorem(options)).process(rules).css
511
+ expect(processed).toBe(expected)
512
+ })
513
+
514
+ it('{platform: \'weapp\', designWidth: 640} ', () => {
515
+ const rules = 'h1 {margin: 0 0 20px;font-size: 40px;line-height: 1.2;}'
516
+ const expected = 'h1 {margin: 0 0 17.09402rpx;font-size: 34.18803rpx;line-height: 1.2;}'
517
+ const options = {
518
+ platform: 'weapp',
519
+ designWidth: 640
520
+ }
521
+ const processed = postcss(pxtorem(options)).process(rules).css
522
+ expect(processed).toBe(expected)
523
+ })
524
+ })
525
+
526
+ describe('platform 为 h5', () => {
527
+ it('{platform: \'h5\', designWidth: 750} ', () => {
528
+ const rules = 'h1 {margin: 0 0 20px;font-size: 40px;line-height: 1.2;}'
529
+ const expected = 'h1 {margin: 0 0 0.42667rem;font-size: 0.85333rem;line-height: 1.2;}'
530
+ const options = {
531
+ platform: 'h5',
532
+ designWidth: 750
533
+ }
534
+ const processed = postcss(pxtorem(options)).process(rules).css
535
+ expect(processed).toBe(expected)
536
+ })
537
+
538
+ it('{platform: \'h5\', designWidth: 640} ', () => {
539
+ const rules = 'h1 {margin: 0 0 20px;font-size: 40Px;line-height: 1.2;}'
540
+ const expected = 'h1 {margin: 0 0 0.5rem;font-size: 40Px;line-height: 1.2;}'
541
+ const options = {
542
+ platform: 'h5',
543
+ designWidth: 640
544
+ }
545
+ const processed = postcss(pxtorem(options)).process(rules).css
546
+ expect(processed).toBe(expected)
547
+ })
548
+ })
549
+
550
+ describe('platform 为 h5,文件头部带注释的不转换', () => {
551
+ it('{platform: \'h5\', designWidth: 640} ', () => {
552
+ const rules = '/*postcss-pxtransform disable*/ h1 {margin: 0 0 20px;font-size: 40Px;line-height: 1.2;}'
553
+ const options = {
554
+ platform: 'h5',
555
+ designWidth: 640
556
+ }
557
+ const processed = postcss(pxtorem(options)).process(rules).css
558
+ expect(processed).toBe(rules)
559
+ })
560
+ })
561
+
562
+ describe('platform 为 h5,指定 h5 平台保留', () => {
563
+ it('{platform: \'h5\', designWidth: 640} ', () => {
564
+ const rules = '/* #ifdef h5 */ h1 {margin: 0 0 20Px;font-size: 40Px;line-height: 1.2;}/* #endif */'
565
+ const options = {
566
+ platform: 'h5',
567
+ designWidth: 640
568
+ }
569
+ const processed = postcss(pxtorem(options)).process(rules).css
570
+ expect(processed).toBe(rules)
571
+ })
572
+ })
573
+
574
+ describe('platform 为 h5,指定平台 rn 平台保留', () => {
575
+ it('{platform: \'h5\', designWidth: 640} ', () => {
576
+ const rules = '/* #ifdef rn */ h1 {margin: 0 0 20px;font-size: 40Px;line-height: 1.2;}/* #endif */ .test{}'
577
+ const options = {
578
+ platform: 'h5',
579
+ designWidth: 640
580
+ }
581
+ const processed = postcss(pxtorem(options)).process(rules).css
582
+ expect(processed).toBe('/* #ifdef rn *//* #endif */ .test{}')
583
+ })
584
+ })
585
+
586
+ describe('platform 为 rn,指定平台 h5 rn 平台保留', () => {
587
+ it('{platform: \'rn\', designWidth: 640} ', () => {
588
+ const rules = '/* #ifdef h5 rn */ h1 {margin: 0 0 20Px;font-size: 40Px;line-height: 1.2;}/* #endif */ .test{}'
589
+ const options = {
590
+ platform: 'rn',
591
+ designWidth: 640
592
+ }
593
+ const processed = postcss(pxtorem(options)).process(rules).css
594
+ expect(processed).toBe(rules)
595
+ })
596
+ })
597
+
598
+ describe('platform 为 h5,指定平台 rn 平台剔除', () => {
599
+ it('{platform: \'h5\', designWidth: 640} ', () => {
600
+ const rules = '/* #ifndef rn */ h1 {margin: 0 0 20Px;font-size: 40Px;line-height: 1.2;}/* #endif */ .test{}'
601
+ const options = {
602
+ platform: 'h5',
603
+ designWidth: 640
604
+ }
605
+ const processed = postcss(pxtorem(options)).process(rules).css
606
+ expect(processed).toBe(rules)
607
+ })
608
+ })
609
+
610
+ describe('platform 为 h5,指定平台 h5 平台剔除', () => {
611
+ it('{platform: \'h5\', designWidth: 640} ', () => {
612
+ const rules = '/* #ifndef h5 */ h1 {margin: 0 0 20px;font-size: 40Px;line-height: 1.2;}/* #endif */ .test{}'
613
+ const options = {
614
+ platform: 'h5',
615
+ designWidth: 640
616
+ }
617
+ const processed = postcss(pxtorem(options)).process(rules).css
618
+ expect(processed).toBe('/* #ifndef h5 *//* #endif */ .test{}')
619
+ })
620
+ })
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
3
  const postcss = require('postcss')
4
- const objectAssign = require('object-assign')
5
4
  const pxRegex = require('./lib/pixel-unit-regex')
5
+ const PXRegex = require('./lib/pixel-upper-unit-regex')
6
6
  const filterPropList = require('./lib/filter-prop-list')
7
7
 
8
8
  const defaults = {
@@ -44,11 +44,6 @@ module.exports = postcss.plugin('postcss-pxtransform', function (options) {
44
44
  options = Object.assign(DEFAULT_WEAPP_OPTIONS, options || {})
45
45
 
46
46
  switch (options.platform) {
47
- case 'weapp': {
48
- options.rootValue = 1 / options.deviceRatio[options.designWidth]
49
- targetUnit = 'rpx'
50
- break
51
- }
52
47
  case 'h5': {
53
48
  options.rootValue = baseFontSize * options.designWidth / 640
54
49
  targetUnit = 'rem'
@@ -59,11 +54,26 @@ module.exports = postcss.plugin('postcss-pxtransform', function (options) {
59
54
  targetUnit = 'px'
60
55
  break
61
56
  }
57
+ case 'quickapp': {
58
+ options.rootValue = 1
59
+ targetUnit = 'px'
60
+ break
61
+ }
62
+ case 'harmony': {
63
+ options.rootValue = 1 / options.deviceRatio[options.designWidth]
64
+ targetUnit = 'px'
65
+ break
66
+ }
67
+ default: {
68
+ // mini-program
69
+ options.rootValue = 1 / options.deviceRatio[options.designWidth]
70
+ targetUnit = 'rpx'
71
+ }
62
72
  }
63
73
 
64
74
  convertLegacyOptions(options)
65
75
 
66
- const opts = objectAssign({}, defaults, options)
76
+ const opts = Object.assign({}, defaults, options)
67
77
  const onePxTransform = typeof options.onePxTransform === 'undefined' ? true : options.onePxTransform
68
78
  const pxReplace = createPxReplace(opts.rootValue, opts.unitPrecision,
69
79
  opts.minPixelValue, onePxTransform)
@@ -98,6 +108,27 @@ module.exports = postcss.plugin('postcss-pxtransform', function (options) {
98
108
  })
99
109
  }
100
110
 
111
+ // PX -> vp in harmony
112
+ if (options.platform === 'harmony') {
113
+ css.walkDecls(function (decl) {
114
+ if (decl.value.indexOf('PX') === -1) return
115
+ const value = decl.value.replace(PXRegex, function (m, _$1, $2) {
116
+ return m.replace($2, 'vp')
117
+ })
118
+ decl.value = value
119
+ })
120
+
121
+ if (opts.mediaQuery) {
122
+ css.walkAtRules('media', function (rule) {
123
+ if (rule.params.indexOf('PX') === -1) return
124
+ const value = rule.params.replace(PXRegex, function (m, _$1, $2) {
125
+ return m.replace($2, 'vp')
126
+ })
127
+ rule.params = value
128
+ })
129
+ }
130
+ }
131
+
101
132
  /* #ifdef %PLATFORM% */
102
133
  // 平台特有样式
103
134
  /* #endif */
@@ -0,0 +1,11 @@
1
+ /*eslint-disable*/
2
+
3
+ // excluding regex trick: http://www.rexegg.com/regex-best-trick.html
4
+
5
+ // Not anything inside double quotes
6
+ // Not anything inside single quotes
7
+ // Not anything inside url()
8
+ // Any digit followed by PX
9
+ // !singlequotes|!doublequotes|!url()|pixelunit
10
+
11
+ module.exports = /"[^"]+"|'[^']+'|url\([^\)]+\)|(\d*\.?\d+)(PX)/g
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-pxtransform",
3
- "version": "3.3.14",
3
+ "version": "3.5.0-canary.0",
4
4
  "description": "PostCSS plugin px 转小程序 rpx及h5 rem 单位",
5
5
  "keywords": [
6
6
  "postcss",
@@ -19,8 +19,7 @@
19
19
  },
20
20
  "homepage": "https://github.com/NervJS/taro#readme",
21
21
  "dependencies": {
22
- "postcss": "^6.0.16",
23
- "postcss-pxtorem": "^4.0.1"
22
+ "postcss": "^6.0.22"
24
23
  },
25
24
  "scripts": {
26
25
  "test": "jest"
@@ -29,5 +28,5 @@
29
28
  "testEnvironment": "node"
30
29
  },
31
30
  "main": "index.js",
32
- "gitHead": "ffd2b33c2a760094372a9ec69735ab9c4d1877e5"
31
+ "gitHead": "a0222bc41bc05b0e34413d6db3de963d777a5015"
33
32
  }
package/CHANGELOG.md DELETED
@@ -1,2 +0,0 @@
1
- # Change Log
2
- This project adheres to [Semantic Versioning](http://semver.org/).