resolution.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. let FractionJs = require('fraction.js')
  2. let Prefixer = require('./prefixer')
  3. let utils = require('./utils')
  4. const REGEXP = /(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi
  5. const SPLIT = /(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i
  6. class Resolution extends Prefixer {
  7. /**
  8. * Remove prefixed queries
  9. */
  10. clean(rule) {
  11. if (!this.bad) {
  12. this.bad = []
  13. for (let prefix of this.prefixes) {
  14. this.bad.push(this.prefixName(prefix, 'min'))
  15. this.bad.push(this.prefixName(prefix, 'max'))
  16. }
  17. }
  18. rule.params = utils.editList(rule.params, queries => {
  19. return queries.filter(query => this.bad.every(i => !query.includes(i)))
  20. })
  21. }
  22. /**
  23. * Return prefixed query name
  24. */
  25. prefixName(prefix, name) {
  26. if (prefix === '-moz-') {
  27. return name + '--moz-device-pixel-ratio'
  28. } else {
  29. return prefix + name + '-device-pixel-ratio'
  30. }
  31. }
  32. /**
  33. * Return prefixed query
  34. */
  35. prefixQuery(prefix, name, colon, value, units) {
  36. value = new FractionJs(value)
  37. // 1dpcm = 2.54dpi
  38. // 1dppx = 96dpi
  39. if (units === 'dpi') {
  40. value = value.div(96)
  41. } else if (units === 'dpcm') {
  42. value = value.mul(2.54).div(96)
  43. }
  44. value = value.simplify()
  45. if (prefix === '-o-') {
  46. value = value.n + '/' + value.d
  47. }
  48. return this.prefixName(prefix, name) + colon + value
  49. }
  50. /**
  51. * Add prefixed queries
  52. */
  53. process(rule) {
  54. let parent = this.parentPrefix(rule)
  55. let prefixes = parent ? [parent] : this.prefixes
  56. rule.params = utils.editList(rule.params, (origin, prefixed) => {
  57. for (let query of origin) {
  58. if (
  59. !query.includes('min-resolution') &&
  60. !query.includes('max-resolution')
  61. ) {
  62. prefixed.push(query)
  63. continue
  64. }
  65. for (let prefix of prefixes) {
  66. let processed = query.replace(REGEXP, str => {
  67. let parts = str.match(SPLIT)
  68. return this.prefixQuery(
  69. prefix,
  70. parts[1],
  71. parts[2],
  72. parts[3],
  73. parts[4]
  74. )
  75. })
  76. prefixed.push(processed)
  77. }
  78. prefixed.push(query)
  79. }
  80. return utils.uniq(prefixed)
  81. })
  82. }
  83. }
  84. module.exports = Resolution