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. * Return prefixed query name
  9. */
  10. prefixName(prefix, name) {
  11. if (prefix === '-moz-') {
  12. return name + '--moz-device-pixel-ratio'
  13. } else {
  14. return prefix + name + '-device-pixel-ratio'
  15. }
  16. }
  17. /**
  18. * Return prefixed query
  19. */
  20. prefixQuery(prefix, name, colon, value, units) {
  21. value = new FractionJs(value)
  22. // 1dpcm = 2.54dpi
  23. // 1dppx = 96dpi
  24. if (units === 'dpi') {
  25. value = value.div(96)
  26. } else if (units === 'dpcm') {
  27. value = value.mul(2.54).div(96)
  28. }
  29. value = value.simplify()
  30. if (prefix === '-o-') {
  31. value = value.n + '/' + value.d
  32. }
  33. return this.prefixName(prefix, name) + colon + value
  34. }
  35. /**
  36. * Remove prefixed queries
  37. */
  38. clean(rule) {
  39. if (!this.bad) {
  40. this.bad = []
  41. for (let prefix of this.prefixes) {
  42. this.bad.push(this.prefixName(prefix, 'min'))
  43. this.bad.push(this.prefixName(prefix, 'max'))
  44. }
  45. }
  46. rule.params = utils.editList(rule.params, queries => {
  47. return queries.filter(query => this.bad.every(i => !query.includes(i)))
  48. })
  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