├── .gitignore ├── .npmignore ├── .travis.yml ├── README-zh-CN.md ├── README.md ├── index.js ├── package-lock.json ├── package.json └── test ├── customFile ├── fontGear_-1.css ├── fontGear_0.css ├── fontGear_1.css ├── fontGear_2.css ├── fontGear_3.css └── fontGear_4.css ├── flexible.spec.js ├── fontGear ├── fontGear_-1.css ├── fontGear_0.css ├── fontGear_1.css ├── fontGear_2.css ├── fontGear_3.css └── fontGear_4.css ├── fontGearCustom ├── fontGear_-1.css ├── fontGear_0.css ├── fontGear_1.css ├── fontGear_2.css ├── fontGear_3.css └── fontGear_4.css ├── fontGearSource ├── fontGear_-1.css ├── fontGear_0.css ├── fontGear_1.css ├── fontGear_2.css ├── fontGear_3.css └── fontGear_4.css ├── output-custom-2.css ├── output-custom.css ├── output-desktop.css ├── output.css └── source.css /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | *.bak 3 | *.log 4 | *.out 5 | 6 | coverage 7 | node_modules 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | *.bak 3 | *.log 4 | *.out 5 | 6 | coverage 7 | node_modules 8 | test 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "5" 5 | 6 | after_success: 7 | - npm i coveralls 8 | - cat ./coverage/lcov.info | coveralls 9 | -------------------------------------------------------------------------------- /README-zh-CN.md: -------------------------------------------------------------------------------- 1 | # postcss-flexible 0.5.x使用及配置方法 2 | ------ 3 | 4 | postcss-flexible 0.5.x此次主要更新目的是为了满足用户根据不同的fontGear获得不同的css数据结构的需求。本次更新主要增加以下自定义配置项: 5 | 6 | > * `fontGear`: array, default `[-1, 0, 1, 2, 3, 4]`, 需要使用的字体档位 7 | > * `enableFontSetting`: boolean, default `false`, 是否开启字体档位功能 8 | > * `addFontSizeToSelector`: function, 用户自定义如何针对不同档位输出计算后的值 9 | > * `outputCSSFile`: function, 用户自定义输出css 10 | 11 | 12 | ------ 13 | 14 | ## 主要函数介绍 15 | 16 | addFontSizeToSelector(originFontSize, gear, baseDpr) -> {Number} 17 | 在原始css中定义的值(originFontSize),根据字体档位(gear)和基础dpr(baseDpr),通过插件计算,返回生成新的值。插件默认为每一个档位之间的差值为1px。 18 | ### 函数定义 19 | ```javascript 20 | var addFontSizeToSelector = function (originFontSize, gear, baseDpr) { 21 | if (!gear) { 22 | gear = 0 23 | } 24 | if (!enableFontSetting) { 25 | return originFontSize 26 | } 27 | if (options.addFontSizeToSelector) { 28 | return options.addFontSizeToSelector(originFontSize, gear, baseDpr) 29 | } 30 | return +originFontSize + gear*baseDpr 31 | ``` 32 | ### 函数参数 33 | | 参数名 | 类型 | 描述 | 34 | | :- | 35 | | `originFontSize`| string \| Number | 原始css中定义的值 | 36 | | `gear` | Number | 字体档位 | 37 | | `baseDpr` | Number | 基础dpr | 38 | ### 返回值 39 | 返回一个数字类型的值(Number) 40 | 41 | outputCSSFile(gear, clonedRoot) -> {undefined} 42 | 在用户开启字体档位功能后,用户可重写outputCSSFile方法,插件在每次遍历fontGear生成修改后的clonedRoot后,会调用此函数,并将clonedRoot作为参数传递,用户可以自定义以何种方式处理该css(可输出文件,也可在控制台中打印) 43 | ### 函数定义 44 | ```javascript 45 | var outputCSSFile = options.outputCSSFile || function (gear, clonedRoot) {} 46 | ``` 47 | ### 函数参数 48 | | 参数名 | 类型 | 描述 | 49 | | :- | 50 | | `gear`| string \| Number | 字体档位 | 51 | | `clonedRoot` | postcss结构 | 修改后的postcss结构 | 52 | ### 返回值 53 | 无返回值 54 | 55 | 56 | ---------- 57 | 58 | 59 | ## 如何使用 60 | ### webpack配置 61 | 若用户开启输出字体档位功能,需要在webpack.config.js中对postcss-flexible插件添加对应属性,以下为将不同字体档位的css文件输出到static目录(生产环境在根目录)下的配置文件片段: 62 | 63 | ```javascript 64 | // 因为要输出文件的关系,这里需要引入fs 65 | import fs from 'fs' 66 | 67 | 68 | function deleteFolderRecursive (path) { 69 | if (fs.existsSync(path)) { 70 | fs.readdirSync(path).forEach(function (file) { 71 | const curPath = path + '/' + file 72 | if (fs.statSync(curPath).isDirectory()) { // recurse 73 | deleteFolderRecursive(curPath) 74 | } else { // delete file 75 | fs.unlinkSync(curPath) 76 | } 77 | }) 78 | fs.rmdirSync(path) 79 | } 80 | } 81 | if (__PROD__) { 82 | // 生产环境下将fontGear文件输出到dist目录,需要在每次compile的时候判断是否存在dist目录,若不存在 则生成,并且在dist目录下生成fontGear目录;若存在fontGear目录则需删除其中的文件 83 | if (!fs.existsSync(paths.dist())) { 84 | fs.mkdirSync(paths.dist()) 85 | fs.mkdirSync(paths.dist('fontGear')) 86 | } else { 87 | deleteFolderRecursive(paths.dist('fontGear')) 88 | if (!fs.existsSync(paths.dist('fontGear'))) { 89 | fs.mkdirSync(paths.dist('fontGear')) 90 | } 91 | } 92 | } else { 93 | // 非生产环境下需要在每次compile时删除static下的fontGear目录及文件 94 | if (fs.existsSync(paths.src('static/fontGear'))) { 95 | deleteFolderRecursive(paths.src('static/fontGear')) 96 | } 97 | } 98 | 99 | // ------------------------------------ 100 | // Plugins 101 | // ------------------------------------ 102 | // 用于保存每次调用生成的postcss数据结构,以避免生成重复的样式声明 103 | const cachedRoot = {} 104 | 105 | const vueLoaderOptions = { 106 | postcss: pack => { 107 | return [ 108 | require('postcss-import')({ 109 | path: paths.src(`themes/${config.theme}`) 110 | }), 111 | require('postcss-url')({ 112 | basePath: paths.src('static') 113 | }), 114 | require('postcss-cssnext')({ 115 | // see: https://github.com/ai/browserslist#queries 116 | browsers: 'Android >= 4, iOS >= 7', 117 | features: { 118 | customProperties: { 119 | variables: require(paths.src(`themes/${config.theme}/variables`)) 120 | } 121 | } 122 | }), 123 | require('postcss-browser-reporter')(), 124 | require('postcss-reporter')(), 125 | // 由于开启postcss-flexible的字体档位功能直接输出文件的关系,这里将插件放在postcss插件的最后一 个,以保证其他插件的功能均已转换完成 126 | require('postcss-flexible')({ 127 | remUnit: 75, 128 | enableFontSetting: true, // 开启字体档位功能 129 | fontGear: [-1, 0, 1, 2, 3, 4], // 自定义字体档位 130 | // 自定义输出函数 131 | outputCSSFile: (gear, clonedRoot) => { 132 | const content = clonedRoot.toString() 133 | if (!(gear in cachedRoot)) { 134 | cachedRoot[gear] = [] 135 | } 136 | // 只将没有输出过的postcss结构写入到对应的文件中 137 | if (cachedRoot[gear].indexOf(content) === -1) { 138 | if (__PROD__) { 139 | fs.writeFileSync(paths.dist(`fontGear/fontGear_${gear}.css`), clonedRoot, { 140 | encoding: 'utf8', 141 | flag: 'a' 142 | }) 143 | } else { 144 | if (!fs.existsSync(paths.src('static/fontGear'))) { 145 | fs.mkdirSync(paths.src('static/fontGear')) 146 | } 147 | fs.writeFileSync(paths.src(`static/fontGear/fontGear_${gear}.css`), content, { 148 | encoding: 'utf8', 149 | flag: 'a' 150 | }) 151 | } 152 | cachedRoot[gear].push(content) 153 | } 154 | } 155 | }) 156 | ] 157 | }, 158 | autoprefixer: false 159 | } 160 | 161 | ``` 162 | ### 项目中引入 163 | 在入口文件中获取字体档位,并向根元素添加data-fontgear属性,根据字体档位加载对应的css文件: 164 | ```javascript 165 | if (window.Bridge) { 166 | const appFontSet = window.Bridge.require('im.app.setting.font.size') 167 | const appFontNum = appFontSet.getCurrentGearValue() || 0 168 | const root = document.documentElement 169 | root.setAttribute('data-fontgear', appFontNum) 170 | const link = document.createElement('link') 171 | link.rel = 'stylesheet' 172 | link.type = 'text/css' 173 | link.href = `./fontGear/fontGear_${appFontNum}.css` 174 | document.head.appendChild(link) 175 | } 176 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # postcss-flexible 2 | 3 | This is a [postcss](https://www.npmjs.com/package/postcss) plugin for translating `dpr(...)`, `rem(...)`, `url(...)`. Similar to [px2rem](https://github.com/songsiqi/px2rem-postcss), but using custom function istead of comments for syntax. 4 | 5 | [![Travis](https://img.shields.io/travis/crossjs/postcss-flexible.svg?style=flat-square)](https://travis-ci.org/crossjs/postcss-flexible) 6 | [![Coveralls](https://img.shields.io/coveralls/crossjs/postcss-flexible.svg?style=flat-square)](https://coveralls.io/github/crossjs/postcss-flexible) 7 | [![dependencies](https://david-dm.org/crossjs/postcss-flexible.svg?style=flat-square)](https://david-dm.org/crossjs/postcss-flexible) 8 | [![devDependency Status](https://david-dm.org/crossjs/postcss-flexible/dev-status.svg?style=flat-square)](https://david-dm.org/crossjs/postcss-flexible?type=dev) 9 | [![NPM version](https://img.shields.io/npm/v/postcss-flexible.svg?style=flat-square)](https://npmjs.org/package/postcss-flexible) 10 | 11 | ## Usage 12 | 13 | ### Webpack 14 | 15 | ```js 16 | module.exports = { 17 | module: { 18 | loaders: [ 19 | { 20 | test: /\.css$/, 21 | loader: "style-loader!css-loader!postcss-loader" 22 | } 23 | ] 24 | }, 25 | postcss: function() { 26 | // remUnit defaults to 75 27 | return [require('postcss-flexible')({remUnit: 75})] 28 | } 29 | } 30 | ``` 31 | 32 | ## Example 33 | 34 | Before processing: 35 | 36 | ```css 37 | .selector { 38 | font-size: dpr(32px); 39 | width: rem(75px); 40 | line-height: 3; 41 | /* replace all @[1-3]x in urls: `/a/@2x/x.png`, `/a@2x/x.png` or `/a/x@2x.png` */ 42 | background-image: url(/images/qr@2x.png); 43 | } 44 | ``` 45 | 46 | After processing: 47 | 48 | ```css 49 | .selector { 50 | width: 1rem; 51 | line-height: 3; 52 | } 53 | 54 | [data-dpr="1"] .selector { 55 | font-size: 16px; 56 | background-image: url(/images/qr@1x.png); 57 | } 58 | 59 | [data-dpr="2"] .selector { 60 | font-size: 32px; 61 | background-image: url(/images/qr@2x.png); 62 | } 63 | 64 | [data-dpr="3"] .selector { 65 | font-size: 48px; 66 | background-image: url(/images/qr@3x.png); 67 | } 68 | ``` 69 | 70 | ## options 71 | 72 | - `desktop`: boolean, default `false` 73 | - `baseDpr`: number, default `2` 74 | - `remUnit`: number, default `75` 75 | - `remPrecision`: number, default `6` 76 | - `addPrefixToSelector`: function 77 | - `dprList`: array, default `[3, 2, 1]` 78 | - `fontGear`: array, default `[-1, 0, 1, 2, 3, 4]` 79 | - `enableFontSetting`: boolean, default `false` 80 | - `addFontSizeToSelector`: function 81 | - `outputCSSFile`: function 82 | 83 | ## Change Log 84 | 85 | 86 | ### 0.5.0 87 | 88 | * add: generate different css files with fontGear 89 | * support custom `fontGear` 90 | * support custom `enableFontSetting` 91 | * support custom `addFontSizeToSelector` 92 | * support custom `outputCSSFile` 93 | 94 | ### 0.4.0 95 | 96 | * support custom `dprList` 97 | 98 | ### 0.3.0 99 | 100 | * add option `desktop` and `addPrefixToSelector` 101 | 102 | ### 0.1.0 103 | 104 | * handle `url()` 105 | 106 | ### 0.0.3 107 | 108 | * add `dpr()` and `rem()` 109 | 110 | ### 0.0.0 111 | 112 | * First release. 113 | 114 | ## License 115 | 116 | MIT 117 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var postcss = require('postcss') 4 | var path = require('path') 5 | var fs = require('fs') 6 | 7 | var valueRegExp = /(dpr|rem|url)\((.+?)(px)?\)/ 8 | var dprRegExp = /dpr\((\d+(?:\.\d+)?)px\)/ 9 | 10 | module.exports = postcss.plugin('postcss-flexible', function (options) { 11 | if (!options) { 12 | options = {} 13 | } 14 | 15 | return function (root, result) { 16 | var desktop = !!options.desktop 17 | var baseDpr = options.baseDpr || 2 18 | var remUnit = options.remUnit || 75 19 | var remPrecision = options.remPrecision || 6 20 | var enableFontSetting = options.enableFontSetting || false 21 | var fontGear = Object.prototype.toString.call(options.fontGear) === '[object Array]' ? options.fontGear : [-1, 0, 1, 2, 3, 4] 22 | var addPrefixToSelector = options.addPrefixToSelector || function (selector, prefix) { 23 | if (/^html/.test(selector)) { 24 | return selector.replace(/^html/, 'html' + prefix) 25 | } 26 | return prefix + ' ' + selector 27 | } 28 | var addFontSizeToSelector = function (originFontSize, gear, baseDpr) { 29 | if (!gear) { 30 | gear = 0 31 | } 32 | if (!enableFontSetting) { 33 | return originFontSize 34 | } 35 | if (options.addFontSizeToSelector) { 36 | return options.addFontSizeToSelector(originFontSize, gear, baseDpr) 37 | } 38 | return +originFontSize + gear*baseDpr 39 | } 40 | var outputCSSFile = options.outputCSSFile || function (gear, clonedRoot) {} 41 | var dprList = (options.dprList || [3, 2, 1]).sort().reverse() 42 | fontGear = fontGear.sort().reverse() 43 | var urlRegExp = new RegExp('url\\([\'"]?\\S+?@(' + dprList.join('|') + ')x\\S+?[\'"]?\\)') 44 | 45 | // get calculated value of px or rem 46 | function getCalcValue (value, dpr, gear) { 47 | var valueGlobalRegExp = new RegExp(valueRegExp.source, 'g') 48 | 49 | function getValue(val, type) { 50 | val = parseFloat(val.toFixed(remPrecision)) // control decimal precision of the calculated value 51 | return val == 0 ? val : val + type 52 | } 53 | return value.replace(valueGlobalRegExp, function ($0, $1, $2) { 54 | if ($1 === 'url') { 55 | if (dpr) { 56 | return 'url(' + $2.replace(new RegExp('@(' + dprList.join('|') + ')x', 'g'), '@' + dpr + 'x') + ')' 57 | } 58 | } else if ($1 === 'dpr') { 59 | if (dpr) { 60 | return getValue(addFontSizeToSelector($2, gear, baseDpr) * dpr / baseDpr, 'px') 61 | } 62 | } else if ($1 === 'rem') { 63 | return getValue($2 / remUnit, 'rem') 64 | } 65 | return $0 66 | }) 67 | } 68 | 69 | function handleDesktop (rule) { 70 | rule.walkDecls(function (decl) { 71 | if (valueRegExp.test(decl.value)) { 72 | if (decl.value === '0px') { 73 | decl.value = '0' 74 | } else { 75 | if (dprRegExp.test(decl.value) || urlRegExp.test(decl.value)) { 76 | decl.value = getCalcValue(decl.value, baseDpr) 77 | } else { 78 | // only has rem() 79 | decl.value = getCalcValue(decl.value) 80 | } 81 | } 82 | } 83 | }) 84 | } 85 | 86 | function handleMobile (rule, gear) { 87 | if (rule.selector.indexOf('[data-dpr="') !== -1) { 88 | return 89 | } 90 | var newRules = [] 91 | var hasDecls = false 92 | 93 | for (var i = 0; i < dprList.length; i++) { 94 | var prefix = gear !== undefined ? '[data-dpr="' + dprList[i] + '"][data-fontgear="' + gear + '"]' :'[data-dpr="' + dprList[i] + '"]' 95 | var newRule = postcss.rule({ 96 | selectors: rule.selectors.map(function (sel) { 97 | return addPrefixToSelector(sel, prefix) 98 | }), 99 | type: rule.type, 100 | customGear: gear 101 | }) 102 | newRules.push(newRule) 103 | } 104 | 105 | rule.walkDecls(function (decl) { 106 | if (valueRegExp.test(decl.value)) { 107 | if (decl.value === '0px') { 108 | decl.value = '0' 109 | } else { 110 | if (dprRegExp.test(decl.value) || urlRegExp.test(decl.value)) { 111 | // generate 3 new decls and put them in the new rules which has [data-dpr] 112 | newRules.forEach(function (newRule, index) { 113 | var newDecl = postcss.decl({ 114 | prop: decl.prop, 115 | value: getCalcValue(decl.value, dprList[index % dprList.length], newRule.customGear) 116 | }) 117 | // filter out background prop when walking the clonedRoot 118 | if (!/background/g.test(decl.prop) || (gear === undefined)) { 119 | newRule.append(newDecl) 120 | } 121 | }) 122 | hasDecls = true 123 | decl.remove() // delete this rule 124 | } else { 125 | // only has rem() 126 | decl.value = getCalcValue(decl.value) 127 | } 128 | } 129 | } 130 | }) 131 | 132 | // if the updated rule is not empty, insert it into its parent Node 133 | if (hasDecls && newRule.nodes.length) { 134 | newRules.forEach(function (newRule) { 135 | rule.parent.insertAfter(rule, newRule) 136 | }) 137 | } 138 | 139 | // if the origin rule has no declarations, delete it 140 | // delete the origin rules when walking the clonedRoot 141 | if (!rule.nodes.length || gear !== undefined) { 142 | rule.remove() 143 | } 144 | } 145 | if (enableFontSetting) { 146 | for (var j = 0; j < fontGear.length; j++) { 147 | var gear = fontGear[j] 148 | // clone the root element so that the operation blow won't distructe the origin root element 149 | var clonedRoot = root.clone() 150 | clonedRoot.walkRules(function (rule) { 151 | desktop ? handleDesktop(rule) : handleMobile(rule, gear) 152 | }) 153 | clonedRoot.walkAtRules(function(atRule) { 154 | if (!atRule.nodes.length) { 155 | atRule.remove() 156 | } 157 | }) 158 | // output the css file with different fontGear 159 | outputCSSFile(gear, clonedRoot) 160 | } 161 | } 162 | root.walkRules(function (rule) { 163 | desktop ? handleDesktop(rule) : handleMobile(rule) 164 | }) 165 | } 166 | }) 167 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-flexible", 3 | "version": "0.4.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.0.9", 9 | "resolved": "http://registry.npm.sdp.nd/abbrev/download/abbrev-1.0.9.tgz", 10 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", 11 | "dev": true 12 | }, 13 | "amdefine": { 14 | "version": "1.0.1", 15 | "resolved": "http://registry.npm.sdp.nd/amdefine/download/amdefine-1.0.1.tgz", 16 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 17 | "dev": true, 18 | "optional": true 19 | }, 20 | "ansi-regex": { 21 | "version": "2.1.1", 22 | "resolved": "http://registry.npm.sdp.nd/ansi-regex/download/ansi-regex-2.1.1.tgz", 23 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 24 | }, 25 | "ansi-styles": { 26 | "version": "2.2.1", 27 | "resolved": "http://registry.npm.sdp.nd/ansi-styles/download/ansi-styles-2.2.1.tgz", 28 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" 29 | }, 30 | "argparse": { 31 | "version": "1.0.10", 32 | "resolved": "http://registry.npm.sdp.nd/argparse/download/argparse-1.0.10.tgz", 33 | "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", 34 | "dev": true, 35 | "requires": { 36 | "sprintf-js": "1.0.3" 37 | } 38 | }, 39 | "async": { 40 | "version": "1.5.2", 41 | "resolved": "http://registry.npm.sdp.nd/async/download/async-1.5.2.tgz", 42 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 43 | "dev": true 44 | }, 45 | "balanced-match": { 46 | "version": "1.0.0", 47 | "resolved": "http://registry.npm.sdp.nd/balanced-match/download/balanced-match-1.0.0.tgz", 48 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 49 | "dev": true 50 | }, 51 | "brace-expansion": { 52 | "version": "1.1.11", 53 | "resolved": "http://registry.npm.sdp.nd/brace-expansion/download/brace-expansion-1.1.11.tgz", 54 | "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", 55 | "dev": true, 56 | "requires": { 57 | "balanced-match": "1.0.0", 58 | "concat-map": "0.0.1" 59 | } 60 | }, 61 | "browser-stdout": { 62 | "version": "1.3.0", 63 | "resolved": "http://registry.npm.sdp.nd/browser-stdout/download/browser-stdout-1.3.0.tgz", 64 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", 65 | "dev": true 66 | }, 67 | "chalk": { 68 | "version": "1.1.3", 69 | "resolved": "http://registry.npm.sdp.nd/chalk/download/chalk-1.1.3.tgz", 70 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 71 | "requires": { 72 | "ansi-styles": "2.2.1", 73 | "escape-string-regexp": "1.0.5", 74 | "has-ansi": "2.0.0", 75 | "strip-ansi": "3.0.1", 76 | "supports-color": "2.0.0" 77 | }, 78 | "dependencies": { 79 | "supports-color": { 80 | "version": "2.0.0", 81 | "resolved": "http://registry.npm.sdp.nd/supports-color/download/supports-color-2.0.0.tgz", 82 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" 83 | } 84 | } 85 | }, 86 | "commander": { 87 | "version": "2.17.1", 88 | "resolved": "http://registry.npm.sdp.nd/commander/download/commander-2.17.1.tgz", 89 | "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78=", 90 | "dev": true, 91 | "optional": true 92 | }, 93 | "concat-map": { 94 | "version": "0.0.1", 95 | "resolved": "http://registry.npm.sdp.nd/concat-map/download/concat-map-0.0.1.tgz", 96 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 97 | "dev": true 98 | }, 99 | "debug": { 100 | "version": "2.6.8", 101 | "resolved": "http://registry.npm.sdp.nd/debug/download/debug-2.6.8.tgz", 102 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", 103 | "dev": true, 104 | "requires": { 105 | "ms": "2.0.0" 106 | } 107 | }, 108 | "deep-is": { 109 | "version": "0.1.3", 110 | "resolved": "http://registry.npm.sdp.nd/deep-is/download/deep-is-0.1.3.tgz", 111 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 112 | "dev": true 113 | }, 114 | "diff": { 115 | "version": "3.2.0", 116 | "resolved": "http://registry.npm.sdp.nd/diff/download/diff-3.2.0.tgz", 117 | "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", 118 | "dev": true 119 | }, 120 | "escape-string-regexp": { 121 | "version": "1.0.5", 122 | "resolved": "http://registry.npm.sdp.nd/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", 123 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 124 | }, 125 | "escodegen": { 126 | "version": "1.8.1", 127 | "resolved": "http://registry.npm.sdp.nd/escodegen/download/escodegen-1.8.1.tgz", 128 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 129 | "dev": true, 130 | "requires": { 131 | "esprima": "2.7.3", 132 | "estraverse": "1.9.3", 133 | "esutils": "2.0.2", 134 | "optionator": "0.8.2", 135 | "source-map": "0.2.0" 136 | }, 137 | "dependencies": { 138 | "source-map": { 139 | "version": "0.2.0", 140 | "resolved": "http://registry.npm.sdp.nd/source-map/download/source-map-0.2.0.tgz", 141 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 142 | "dev": true, 143 | "optional": true, 144 | "requires": { 145 | "amdefine": "1.0.1" 146 | } 147 | } 148 | } 149 | }, 150 | "esprima": { 151 | "version": "2.7.3", 152 | "resolved": "http://registry.npm.sdp.nd/esprima/download/esprima-2.7.3.tgz", 153 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 154 | "dev": true 155 | }, 156 | "estraverse": { 157 | "version": "1.9.3", 158 | "resolved": "http://registry.npm.sdp.nd/estraverse/download/estraverse-1.9.3.tgz", 159 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 160 | "dev": true 161 | }, 162 | "esutils": { 163 | "version": "2.0.2", 164 | "resolved": "http://registry.npm.sdp.nd/esutils/download/esutils-2.0.2.tgz", 165 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 166 | "dev": true 167 | }, 168 | "fast-levenshtein": { 169 | "version": "2.0.6", 170 | "resolved": "http://registry.npm.sdp.nd/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", 171 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 172 | "dev": true 173 | }, 174 | "fs.realpath": { 175 | "version": "1.0.0", 176 | "resolved": "http://registry.npm.sdp.nd/fs.realpath/download/fs.realpath-1.0.0.tgz", 177 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 178 | "dev": true 179 | }, 180 | "glob": { 181 | "version": "5.0.15", 182 | "resolved": "http://registry.npm.sdp.nd/glob/download/glob-5.0.15.tgz", 183 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 184 | "dev": true, 185 | "requires": { 186 | "inflight": "1.0.6", 187 | "inherits": "2.0.3", 188 | "minimatch": "3.0.4", 189 | "once": "1.4.0", 190 | "path-is-absolute": "1.0.1" 191 | } 192 | }, 193 | "graceful-readlink": { 194 | "version": "1.0.1", 195 | "resolved": "http://registry.npm.sdp.nd/graceful-readlink/download/graceful-readlink-1.0.1.tgz", 196 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", 197 | "dev": true 198 | }, 199 | "growl": { 200 | "version": "1.9.2", 201 | "resolved": "http://registry.npm.sdp.nd/growl/download/growl-1.9.2.tgz", 202 | "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", 203 | "dev": true 204 | }, 205 | "handlebars": { 206 | "version": "4.0.12", 207 | "resolved": "http://registry.npm.sdp.nd/handlebars/download/handlebars-4.0.12.tgz", 208 | "integrity": "sha1-LBXIqW1G2l4mZwBRi6jLjZGdW8U=", 209 | "dev": true, 210 | "requires": { 211 | "async": "2.6.1", 212 | "optimist": "0.6.1", 213 | "source-map": "0.6.1", 214 | "uglify-js": "3.4.9" 215 | }, 216 | "dependencies": { 217 | "async": { 218 | "version": "2.6.1", 219 | "resolved": "http://registry.npm.sdp.nd/async/download/async-2.6.1.tgz", 220 | "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", 221 | "dev": true, 222 | "requires": { 223 | "lodash": "4.17.11" 224 | } 225 | }, 226 | "source-map": { 227 | "version": "0.6.1", 228 | "resolved": "http://registry.npm.sdp.nd/source-map/download/source-map-0.6.1.tgz", 229 | "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", 230 | "dev": true 231 | } 232 | } 233 | }, 234 | "has-ansi": { 235 | "version": "2.0.0", 236 | "resolved": "http://registry.npm.sdp.nd/has-ansi/download/has-ansi-2.0.0.tgz", 237 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 238 | "requires": { 239 | "ansi-regex": "2.1.1" 240 | } 241 | }, 242 | "has-flag": { 243 | "version": "1.0.0", 244 | "resolved": "http://registry.npm.sdp.nd/has-flag/download/has-flag-1.0.0.tgz", 245 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" 246 | }, 247 | "he": { 248 | "version": "1.1.1", 249 | "resolved": "http://registry.npm.sdp.nd/he/download/he-1.1.1.tgz", 250 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 251 | "dev": true 252 | }, 253 | "inflight": { 254 | "version": "1.0.6", 255 | "resolved": "http://registry.npm.sdp.nd/inflight/download/inflight-1.0.6.tgz", 256 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 257 | "dev": true, 258 | "requires": { 259 | "once": "1.4.0", 260 | "wrappy": "1.0.2" 261 | } 262 | }, 263 | "inherits": { 264 | "version": "2.0.3", 265 | "resolved": "http://registry.npm.sdp.nd/inherits/download/inherits-2.0.3.tgz", 266 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 267 | "dev": true 268 | }, 269 | "isexe": { 270 | "version": "2.0.0", 271 | "resolved": "http://registry.npm.sdp.nd/isexe/download/isexe-2.0.0.tgz", 272 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 273 | "dev": true 274 | }, 275 | "istanbul": { 276 | "version": "0.4.5", 277 | "resolved": "http://registry.npm.sdp.nd/istanbul/download/istanbul-0.4.5.tgz", 278 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", 279 | "dev": true, 280 | "requires": { 281 | "abbrev": "1.0.9", 282 | "async": "1.5.2", 283 | "escodegen": "1.8.1", 284 | "esprima": "2.7.3", 285 | "glob": "5.0.15", 286 | "handlebars": "4.0.12", 287 | "js-yaml": "3.12.0", 288 | "mkdirp": "0.5.1", 289 | "nopt": "3.0.6", 290 | "once": "1.4.0", 291 | "resolve": "1.1.7", 292 | "supports-color": "3.2.3", 293 | "which": "1.3.1", 294 | "wordwrap": "1.0.0" 295 | } 296 | }, 297 | "js-base64": { 298 | "version": "2.4.9", 299 | "resolved": "http://registry.npm.sdp.nd/js-base64/download/js-base64-2.4.9.tgz", 300 | "integrity": "sha1-dIkR+wT0imDEdxs3XKxFqA3xHAM=" 301 | }, 302 | "js-yaml": { 303 | "version": "3.12.0", 304 | "resolved": "http://registry.npm.sdp.nd/js-yaml/download/js-yaml-3.12.0.tgz", 305 | "integrity": "sha1-6u1lbsg0TxD1J8a/obbiJE3hZ9E=", 306 | "dev": true, 307 | "requires": { 308 | "argparse": "1.0.10", 309 | "esprima": "4.0.1" 310 | }, 311 | "dependencies": { 312 | "esprima": { 313 | "version": "4.0.1", 314 | "resolved": "http://registry.npm.sdp.nd/esprima/download/esprima-4.0.1.tgz", 315 | "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", 316 | "dev": true 317 | } 318 | } 319 | }, 320 | "json3": { 321 | "version": "3.3.2", 322 | "resolved": "http://registry.npm.sdp.nd/json3/download/json3-3.3.2.tgz", 323 | "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", 324 | "dev": true 325 | }, 326 | "levn": { 327 | "version": "0.3.0", 328 | "resolved": "http://registry.npm.sdp.nd/levn/download/levn-0.3.0.tgz", 329 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 330 | "dev": true, 331 | "requires": { 332 | "prelude-ls": "1.1.2", 333 | "type-check": "0.3.2" 334 | } 335 | }, 336 | "lodash": { 337 | "version": "4.17.11", 338 | "resolved": "http://registry.npm.sdp.nd/lodash/download/lodash-4.17.11.tgz", 339 | "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=", 340 | "dev": true 341 | }, 342 | "lodash._baseassign": { 343 | "version": "3.2.0", 344 | "resolved": "http://registry.npm.sdp.nd/lodash._baseassign/download/lodash._baseassign-3.2.0.tgz", 345 | "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", 346 | "dev": true, 347 | "requires": { 348 | "lodash._basecopy": "3.0.1", 349 | "lodash.keys": "3.1.2" 350 | } 351 | }, 352 | "lodash._basecopy": { 353 | "version": "3.0.1", 354 | "resolved": "http://registry.npm.sdp.nd/lodash._basecopy/download/lodash._basecopy-3.0.1.tgz", 355 | "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", 356 | "dev": true 357 | }, 358 | "lodash._basecreate": { 359 | "version": "3.0.3", 360 | "resolved": "http://registry.npm.sdp.nd/lodash._basecreate/download/lodash._basecreate-3.0.3.tgz", 361 | "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", 362 | "dev": true 363 | }, 364 | "lodash._getnative": { 365 | "version": "3.9.1", 366 | "resolved": "http://registry.npm.sdp.nd/lodash._getnative/download/lodash._getnative-3.9.1.tgz", 367 | "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", 368 | "dev": true 369 | }, 370 | "lodash._isiterateecall": { 371 | "version": "3.0.9", 372 | "resolved": "http://registry.npm.sdp.nd/lodash._isiterateecall/download/lodash._isiterateecall-3.0.9.tgz", 373 | "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", 374 | "dev": true 375 | }, 376 | "lodash.create": { 377 | "version": "3.1.1", 378 | "resolved": "http://registry.npm.sdp.nd/lodash.create/download/lodash.create-3.1.1.tgz", 379 | "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", 380 | "dev": true, 381 | "requires": { 382 | "lodash._baseassign": "3.2.0", 383 | "lodash._basecreate": "3.0.3", 384 | "lodash._isiterateecall": "3.0.9" 385 | } 386 | }, 387 | "lodash.isarguments": { 388 | "version": "3.1.0", 389 | "resolved": "http://registry.npm.sdp.nd/lodash.isarguments/download/lodash.isarguments-3.1.0.tgz", 390 | "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", 391 | "dev": true 392 | }, 393 | "lodash.isarray": { 394 | "version": "3.0.4", 395 | "resolved": "http://registry.npm.sdp.nd/lodash.isarray/download/lodash.isarray-3.0.4.tgz", 396 | "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", 397 | "dev": true 398 | }, 399 | "lodash.keys": { 400 | "version": "3.1.2", 401 | "resolved": "http://registry.npm.sdp.nd/lodash.keys/download/lodash.keys-3.1.2.tgz", 402 | "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", 403 | "dev": true, 404 | "requires": { 405 | "lodash._getnative": "3.9.1", 406 | "lodash.isarguments": "3.1.0", 407 | "lodash.isarray": "3.0.4" 408 | } 409 | }, 410 | "minimatch": { 411 | "version": "3.0.4", 412 | "resolved": "http://registry.npm.sdp.nd/minimatch/download/minimatch-3.0.4.tgz", 413 | "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", 414 | "dev": true, 415 | "requires": { 416 | "brace-expansion": "1.1.11" 417 | } 418 | }, 419 | "minimist": { 420 | "version": "0.0.10", 421 | "resolved": "http://registry.npm.sdp.nd/minimist/download/minimist-0.0.10.tgz", 422 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", 423 | "dev": true 424 | }, 425 | "mkdirp": { 426 | "version": "0.5.1", 427 | "resolved": "http://registry.npm.sdp.nd/mkdirp/download/mkdirp-0.5.1.tgz", 428 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 429 | "dev": true, 430 | "requires": { 431 | "minimist": "0.0.8" 432 | }, 433 | "dependencies": { 434 | "minimist": { 435 | "version": "0.0.8", 436 | "resolved": "http://registry.npm.sdp.nd/minimist/download/minimist-0.0.8.tgz", 437 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 438 | "dev": true 439 | } 440 | } 441 | }, 442 | "mocha": { 443 | "version": "3.5.3", 444 | "resolved": "http://registry.npm.sdp.nd/mocha/download/mocha-3.5.3.tgz", 445 | "integrity": "sha1-HgSA/jbS2lhY0etqzDhBiybqog0=", 446 | "dev": true, 447 | "requires": { 448 | "browser-stdout": "1.3.0", 449 | "commander": "2.9.0", 450 | "debug": "2.6.8", 451 | "diff": "3.2.0", 452 | "escape-string-regexp": "1.0.5", 453 | "glob": "7.1.1", 454 | "growl": "1.9.2", 455 | "he": "1.1.1", 456 | "json3": "3.3.2", 457 | "lodash.create": "3.1.1", 458 | "mkdirp": "0.5.1", 459 | "supports-color": "3.1.2" 460 | }, 461 | "dependencies": { 462 | "commander": { 463 | "version": "2.9.0", 464 | "resolved": "http://registry.npm.sdp.nd/commander/download/commander-2.9.0.tgz", 465 | "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", 466 | "dev": true, 467 | "requires": { 468 | "graceful-readlink": "1.0.1" 469 | } 470 | }, 471 | "glob": { 472 | "version": "7.1.1", 473 | "resolved": "http://registry.npm.sdp.nd/glob/download/glob-7.1.1.tgz", 474 | "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", 475 | "dev": true, 476 | "requires": { 477 | "fs.realpath": "1.0.0", 478 | "inflight": "1.0.6", 479 | "inherits": "2.0.3", 480 | "minimatch": "3.0.4", 481 | "once": "1.4.0", 482 | "path-is-absolute": "1.0.1" 483 | } 484 | }, 485 | "supports-color": { 486 | "version": "3.1.2", 487 | "resolved": "http://registry.npm.sdp.nd/supports-color/download/supports-color-3.1.2.tgz", 488 | "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", 489 | "dev": true, 490 | "requires": { 491 | "has-flag": "1.0.0" 492 | } 493 | } 494 | } 495 | }, 496 | "ms": { 497 | "version": "2.0.0", 498 | "resolved": "http://registry.npm.sdp.nd/ms/download/ms-2.0.0.tgz", 499 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 500 | "dev": true 501 | }, 502 | "nopt": { 503 | "version": "3.0.6", 504 | "resolved": "http://registry.npm.sdp.nd/nopt/download/nopt-3.0.6.tgz", 505 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 506 | "dev": true, 507 | "requires": { 508 | "abbrev": "1.0.9" 509 | } 510 | }, 511 | "once": { 512 | "version": "1.4.0", 513 | "resolved": "http://registry.npm.sdp.nd/once/download/once-1.4.0.tgz", 514 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 515 | "dev": true, 516 | "requires": { 517 | "wrappy": "1.0.2" 518 | } 519 | }, 520 | "optimist": { 521 | "version": "0.6.1", 522 | "resolved": "http://registry.npm.sdp.nd/optimist/download/optimist-0.6.1.tgz", 523 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 524 | "dev": true, 525 | "requires": { 526 | "minimist": "0.0.10", 527 | "wordwrap": "0.0.3" 528 | }, 529 | "dependencies": { 530 | "wordwrap": { 531 | "version": "0.0.3", 532 | "resolved": "http://registry.npm.sdp.nd/wordwrap/download/wordwrap-0.0.3.tgz", 533 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 534 | "dev": true 535 | } 536 | } 537 | }, 538 | "optionator": { 539 | "version": "0.8.2", 540 | "resolved": "http://registry.npm.sdp.nd/optionator/download/optionator-0.8.2.tgz", 541 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 542 | "dev": true, 543 | "requires": { 544 | "deep-is": "0.1.3", 545 | "fast-levenshtein": "2.0.6", 546 | "levn": "0.3.0", 547 | "prelude-ls": "1.1.2", 548 | "type-check": "0.3.2", 549 | "wordwrap": "1.0.0" 550 | } 551 | }, 552 | "path-is-absolute": { 553 | "version": "1.0.1", 554 | "resolved": "http://registry.npm.sdp.nd/path-is-absolute/download/path-is-absolute-1.0.1.tgz", 555 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 556 | "dev": true 557 | }, 558 | "postcss": { 559 | "version": "5.2.18", 560 | "resolved": "http://registry.npm.sdp.nd/postcss/download/postcss-5.2.18.tgz", 561 | "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", 562 | "requires": { 563 | "chalk": "1.1.3", 564 | "js-base64": "2.4.9", 565 | "source-map": "0.5.7", 566 | "supports-color": "3.2.3" 567 | } 568 | }, 569 | "prelude-ls": { 570 | "version": "1.1.2", 571 | "resolved": "http://registry.npm.sdp.nd/prelude-ls/download/prelude-ls-1.1.2.tgz", 572 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 573 | "dev": true 574 | }, 575 | "resolve": { 576 | "version": "1.1.7", 577 | "resolved": "http://registry.npm.sdp.nd/resolve/download/resolve-1.1.7.tgz", 578 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 579 | "dev": true 580 | }, 581 | "source-map": { 582 | "version": "0.5.7", 583 | "resolved": "http://registry.npm.sdp.nd/source-map/download/source-map-0.5.7.tgz", 584 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 585 | }, 586 | "sprintf-js": { 587 | "version": "1.0.3", 588 | "resolved": "http://registry.npm.sdp.nd/sprintf-js/download/sprintf-js-1.0.3.tgz", 589 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 590 | "dev": true 591 | }, 592 | "strip-ansi": { 593 | "version": "3.0.1", 594 | "resolved": "http://registry.npm.sdp.nd/strip-ansi/download/strip-ansi-3.0.1.tgz", 595 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 596 | "requires": { 597 | "ansi-regex": "2.1.1" 598 | } 599 | }, 600 | "supports-color": { 601 | "version": "3.2.3", 602 | "resolved": "http://registry.npm.sdp.nd/supports-color/download/supports-color-3.2.3.tgz", 603 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 604 | "requires": { 605 | "has-flag": "1.0.0" 606 | } 607 | }, 608 | "type-check": { 609 | "version": "0.3.2", 610 | "resolved": "http://registry.npm.sdp.nd/type-check/download/type-check-0.3.2.tgz", 611 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 612 | "dev": true, 613 | "requires": { 614 | "prelude-ls": "1.1.2" 615 | } 616 | }, 617 | "uglify-js": { 618 | "version": "3.4.9", 619 | "resolved": "http://registry.npm.sdp.nd/uglify-js/download/uglify-js-3.4.9.tgz", 620 | "integrity": "sha1-rwLxgMEgfXZDLkc+0koo9KeCuuM=", 621 | "dev": true, 622 | "optional": true, 623 | "requires": { 624 | "commander": "2.17.1", 625 | "source-map": "0.6.1" 626 | }, 627 | "dependencies": { 628 | "source-map": { 629 | "version": "0.6.1", 630 | "resolved": "http://registry.npm.sdp.nd/source-map/download/source-map-0.6.1.tgz", 631 | "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", 632 | "dev": true, 633 | "optional": true 634 | } 635 | } 636 | }, 637 | "which": { 638 | "version": "1.3.1", 639 | "resolved": "http://registry.npm.sdp.nd/which/download/which-1.3.1.tgz", 640 | "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", 641 | "dev": true, 642 | "requires": { 643 | "isexe": "2.0.0" 644 | } 645 | }, 646 | "wordwrap": { 647 | "version": "1.0.0", 648 | "resolved": "http://registry.npm.sdp.nd/wordwrap/download/wordwrap-1.0.0.tgz", 649 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 650 | "dev": true 651 | }, 652 | "wrappy": { 653 | "version": "1.0.2", 654 | "resolved": "http://registry.npm.sdp.nd/wrappy/download/wrappy-1.0.2.tgz", 655 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 656 | "dev": true 657 | } 658 | } 659 | } 660 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-flexible", 3 | "version": "0.5.4", 4 | "description": "flexible transformer for flexible", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "istanbul cover _mocha", 8 | "test-win": "istanbul cover node_modules/mocha/bin/_mocha" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/crossjs/postcss-flexible.git" 13 | }, 14 | "keywords": [ 15 | "css", 16 | "dpr", 17 | "rem", 18 | "url", 19 | "flexible" 20 | ], 21 | "author": "crossjs", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/crossjs/postcss-flexible/issues" 25 | }, 26 | "homepage": "https://github.com/crossjs/postcss-flexible#readme", 27 | "dependencies": { 28 | "postcss": "^5.2.0" 29 | }, 30 | "devDependencies": { 31 | "istanbul": "0.4.5", 32 | "mocha": "^3.0.2", 33 | "postcss": "^5.2.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/customFile/fontGear_-1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="-1"] .selector, [data-dpr="1"][data-fontgear="-1"] .selector2 { 2 | font-size: 15px 3 | } 4 | [data-dpr="2"][data-fontgear="-1"] .selector, [data-dpr="2"][data-fontgear="-1"] .selector2 { 5 | font-size: 30px 6 | } 7 | [data-dpr="3"][data-fontgear="-1"] .selector, [data-dpr="3"][data-fontgear="-1"] .selector2 { 8 | font-size: 45px 9 | } 10 | [data-dpr="1"][data-fontgear="-1"] .selector3 { 11 | padding: 9px 12 | } 13 | [data-dpr="2"][data-fontgear="-1"] .selector3 { 14 | padding: 18px 15 | } 16 | [data-dpr="3"][data-fontgear="-1"] .selector3 { 17 | padding: 27px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="-1"] body { 21 | margin: 9px 22 | } 23 | [data-dpr="2"][data-fontgear="-1"] body { 24 | margin: 18px 25 | } 26 | [data-dpr="3"][data-fontgear="-1"] body { 27 | margin: 27px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="-1"][dir="rtl"] body { 31 | padding: 3px 32 | } 33 | html[data-dpr="2"][data-fontgear="-1"][dir="rtl"] body { 34 | padding: 6px 35 | } 36 | html[data-dpr="3"][data-fontgear="-1"][dir="rtl"] body { 37 | padding: 9px 38 | } -------------------------------------------------------------------------------- /test/customFile/fontGear_0.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="0"] .selector, [data-dpr="1"][data-fontgear="0"] .selector2 { 2 | font-size: 16px 3 | } 4 | [data-dpr="2"][data-fontgear="0"] .selector, [data-dpr="2"][data-fontgear="0"] .selector2 { 5 | font-size: 32px 6 | } 7 | [data-dpr="3"][data-fontgear="0"] .selector, [data-dpr="3"][data-fontgear="0"] .selector2 { 8 | font-size: 48px 9 | } 10 | [data-dpr="1"][data-fontgear="0"] .selector3 { 11 | padding: 10px 12 | } 13 | [data-dpr="2"][data-fontgear="0"] .selector3 { 14 | padding: 20px 15 | } 16 | [data-dpr="3"][data-fontgear="0"] .selector3 { 17 | padding: 30px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="0"] body { 21 | margin: 10px 22 | } 23 | [data-dpr="2"][data-fontgear="0"] body { 24 | margin: 20px 25 | } 26 | [data-dpr="3"][data-fontgear="0"] body { 27 | margin: 30px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="0"][dir="rtl"] body { 31 | padding: 4px 32 | } 33 | html[data-dpr="2"][data-fontgear="0"][dir="rtl"] body { 34 | padding: 8px 35 | } 36 | html[data-dpr="3"][data-fontgear="0"][dir="rtl"] body { 37 | padding: 12px 38 | } -------------------------------------------------------------------------------- /test/customFile/fontGear_1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="1"] .selector, [data-dpr="1"][data-fontgear="1"] .selector2 { 2 | font-size: 17px 3 | } 4 | [data-dpr="2"][data-fontgear="1"] .selector, [data-dpr="2"][data-fontgear="1"] .selector2 { 5 | font-size: 34px 6 | } 7 | [data-dpr="3"][data-fontgear="1"] .selector, [data-dpr="3"][data-fontgear="1"] .selector2 { 8 | font-size: 51px 9 | } 10 | [data-dpr="1"][data-fontgear="1"] .selector3 { 11 | padding: 11px 12 | } 13 | [data-dpr="2"][data-fontgear="1"] .selector3 { 14 | padding: 22px 15 | } 16 | [data-dpr="3"][data-fontgear="1"] .selector3 { 17 | padding: 33px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="1"] body { 21 | margin: 11px 22 | } 23 | [data-dpr="2"][data-fontgear="1"] body { 24 | margin: 22px 25 | } 26 | [data-dpr="3"][data-fontgear="1"] body { 27 | margin: 33px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="1"][dir="rtl"] body { 31 | padding: 5px 32 | } 33 | html[data-dpr="2"][data-fontgear="1"][dir="rtl"] body { 34 | padding: 10px 35 | } 36 | html[data-dpr="3"][data-fontgear="1"][dir="rtl"] body { 37 | padding: 15px 38 | } -------------------------------------------------------------------------------- /test/customFile/fontGear_2.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="2"] .selector, [data-dpr="1"][data-fontgear="2"] .selector2 { 2 | font-size: 18px 3 | } 4 | [data-dpr="2"][data-fontgear="2"] .selector, [data-dpr="2"][data-fontgear="2"] .selector2 { 5 | font-size: 36px 6 | } 7 | [data-dpr="3"][data-fontgear="2"] .selector, [data-dpr="3"][data-fontgear="2"] .selector2 { 8 | font-size: 54px 9 | } 10 | [data-dpr="1"][data-fontgear="2"] .selector3 { 11 | padding: 12px 12 | } 13 | [data-dpr="2"][data-fontgear="2"] .selector3 { 14 | padding: 24px 15 | } 16 | [data-dpr="3"][data-fontgear="2"] .selector3 { 17 | padding: 36px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="2"] body { 21 | margin: 12px 22 | } 23 | [data-dpr="2"][data-fontgear="2"] body { 24 | margin: 24px 25 | } 26 | [data-dpr="3"][data-fontgear="2"] body { 27 | margin: 36px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="2"][dir="rtl"] body { 31 | padding: 6px 32 | } 33 | html[data-dpr="2"][data-fontgear="2"][dir="rtl"] body { 34 | padding: 12px 35 | } 36 | html[data-dpr="3"][data-fontgear="2"][dir="rtl"] body { 37 | padding: 18px 38 | } -------------------------------------------------------------------------------- /test/customFile/fontGear_3.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="3"] .selector, [data-dpr="1"][data-fontgear="3"] .selector2 { 2 | font-size: 19px 3 | } 4 | [data-dpr="2"][data-fontgear="3"] .selector, [data-dpr="2"][data-fontgear="3"] .selector2 { 5 | font-size: 38px 6 | } 7 | [data-dpr="3"][data-fontgear="3"] .selector, [data-dpr="3"][data-fontgear="3"] .selector2 { 8 | font-size: 57px 9 | } 10 | [data-dpr="1"][data-fontgear="3"] .selector3 { 11 | padding: 13px 12 | } 13 | [data-dpr="2"][data-fontgear="3"] .selector3 { 14 | padding: 26px 15 | } 16 | [data-dpr="3"][data-fontgear="3"] .selector3 { 17 | padding: 39px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="3"] body { 21 | margin: 13px 22 | } 23 | [data-dpr="2"][data-fontgear="3"] body { 24 | margin: 26px 25 | } 26 | [data-dpr="3"][data-fontgear="3"] body { 27 | margin: 39px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="3"][dir="rtl"] body { 31 | padding: 7px 32 | } 33 | html[data-dpr="2"][data-fontgear="3"][dir="rtl"] body { 34 | padding: 14px 35 | } 36 | html[data-dpr="3"][data-fontgear="3"][dir="rtl"] body { 37 | padding: 21px 38 | } -------------------------------------------------------------------------------- /test/customFile/fontGear_4.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="4"] .selector, [data-dpr="1"][data-fontgear="4"] .selector2 { 2 | font-size: 20px 3 | } 4 | [data-dpr="2"][data-fontgear="4"] .selector, [data-dpr="2"][data-fontgear="4"] .selector2 { 5 | font-size: 40px 6 | } 7 | [data-dpr="3"][data-fontgear="4"] .selector, [data-dpr="3"][data-fontgear="4"] .selector2 { 8 | font-size: 60px 9 | } 10 | [data-dpr="1"][data-fontgear="4"] .selector3 { 11 | padding: 14px 12 | } 13 | [data-dpr="2"][data-fontgear="4"] .selector3 { 14 | padding: 28px 15 | } 16 | [data-dpr="3"][data-fontgear="4"] .selector3 { 17 | padding: 42px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="4"] body { 21 | margin: 14px 22 | } 23 | [data-dpr="2"][data-fontgear="4"] body { 24 | margin: 28px 25 | } 26 | [data-dpr="3"][data-fontgear="4"] body { 27 | margin: 42px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="4"][dir="rtl"] body { 31 | padding: 8px 32 | } 33 | html[data-dpr="2"][data-fontgear="4"][dir="rtl"] body { 34 | padding: 16px 35 | } 36 | html[data-dpr="3"][data-fontgear="4"][dir="rtl"] body { 37 | padding: 24px 38 | } -------------------------------------------------------------------------------- /test/flexible.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert') 4 | var path = require('path') 5 | var fs = require('fs') 6 | var postcss = require('postcss') 7 | var flexible = require('../index.js') 8 | 9 | describe('postcss-flexible', function() { 10 | 11 | it('should output right css text', function() { 12 | var srcPath = path.join(__dirname, 'source.css') 13 | var srcText = fs.readFileSync(srcPath, { 14 | encoding: 'utf8' 15 | }) 16 | var outputText = postcss().use(flexible()).process(srcText).css 17 | var expectedText = fs.readFileSync(path.join(__dirname, 'output.css'), { 18 | encoding: 'utf8' 19 | }) 20 | assert.equal(outputText.trim(), expectedText.trim()) 21 | }) 22 | 23 | it('should output right css text for desktop', function() { 24 | var srcPath = path.join(__dirname, 'source.css') 25 | var srcText = fs.readFileSync(srcPath, { 26 | encoding: 'utf8' 27 | }) 28 | var outputText = postcss().use(flexible({ desktop: true })).process(srcText).css 29 | var expectedText = fs.readFileSync(path.join(__dirname, 'output-desktop.css'), { 30 | encoding: 'utf8' 31 | }) 32 | assert.equal(outputText.trim(), expectedText.trim()) 33 | }) 34 | 35 | it('should output right css text with addPrefixToSelector', function() { 36 | var srcPath = path.join(__dirname, 'source.css') 37 | var srcText = fs.readFileSync(srcPath, { 38 | encoding: 'utf8' 39 | }) 40 | var outputText = postcss().use(flexible({ addPrefixToSelector: function(selector, prefix) { 41 | return prefix + ' > ' + selector 42 | } })).process(srcText).css 43 | var expectedText = fs.readFileSync(path.join(__dirname, 'output-custom.css'), { 44 | encoding: 'utf8' 45 | }) 46 | assert.equal(outputText.trim(), expectedText.trim()) 47 | }) 48 | 49 | it('should output right css text with dprList', function() { 50 | var srcPath = path.join(__dirname, 'source.css') 51 | var srcText = fs.readFileSync(srcPath, { 52 | encoding: 'utf8' 53 | }) 54 | var outputText = postcss().use(flexible({ dprList: [4, 2] })).process(srcText).css 55 | var expectedText = fs.readFileSync(path.join(__dirname, 'output-custom-2.css'), { 56 | encoding: 'utf8' 57 | }) 58 | assert.equal(outputText.trim(), expectedText.trim()) 59 | }) 60 | 61 | it('should output right css text with enableFontSetting', function() { 62 | var srcPath = path.join(__dirname, 'source.css') 63 | var srcText = fs.readFileSync(srcPath, { 64 | encoding: 'utf8' 65 | }) 66 | var fontGear = [-1, 0, 1, 2, 3, 4] 67 | var outputCSSFile = function(gear, clonedRoot) { 68 | gear !== undefined && fs.writeFileSync(path.join(__dirname, 'fontGear/fontGear_' + gear +'.css'), clonedRoot, { 69 | encoding: 'utf8' 70 | }) 71 | } 72 | postcss().use(flexible({ 73 | enableFontSetting: true, 74 | fontGear: fontGear, 75 | outputCSSFile: outputCSSFile 76 | })).process(srcText).css 77 | // console.log(outputText) 78 | for (let i = -1, len = fontGear.length - 1; i < len; i++) { 79 | var outputText = fs.readFileSync(path.join(__dirname, 'fontGear/fontGear_' + i +'.css'), { 80 | encoding: 'utf8' 81 | }) 82 | var expectedText = fs.readFileSync(path.join(__dirname, 'fontGearSource/fontGear_' + i +'.css'), { 83 | encoding: 'utf8' 84 | }) 85 | assert.equal(outputText.trim(), expectedText.trim()) 86 | } 87 | }) 88 | it('should output right css text with enableFontSetting and addFontSizeToSelector', function() { 89 | var srcPath = path.join(__dirname, 'source.css') 90 | var srcText = fs.readFileSync(srcPath, { 91 | encoding: 'utf8' 92 | }) 93 | var fontGear = [-1, 0, 1, 2, 3, 4] 94 | var addFontSizeToSelector = function (originFontSize, gear, baseDpr) { 95 | if (!baseDpr) { 96 | baseDpr = 2 97 | } 98 | return +originFontSize + gear*baseDpr*2 99 | } 100 | var outputCSSFile = function(gear, clonedRoot) { 101 | gear !== undefined && fs.writeFileSync(path.join(__dirname, 'fontGear/fontGear_' + gear +'.css'), clonedRoot, { 102 | encoding: 'utf8' 103 | }) 104 | } 105 | var output = postcss().use(flexible({ 106 | enableFontSetting: true, 107 | fontGear: fontGear, 108 | addFontSizeToSelector: addFontSizeToSelector, 109 | outputCSSFile: outputCSSFile 110 | })).process(srcText).css 111 | var expectedText = fs.readFileSync(path.join(__dirname, 'output.css'), { 112 | encoding: 'utf8' 113 | }) 114 | assert.equal(output.trim(), expectedText.trim()) 115 | for (let i = -1, len = fontGear.length - 1; i < len; i++) { 116 | var outputText = fs.readFileSync(path.join(__dirname, 'fontGear/fontGear_' + i +'.css'), { 117 | encoding: 'utf8' 118 | }) 119 | var expectedText = fs.readFileSync(path.join(__dirname, 'fontGearCustom/fontGear_' + i +'.css'), { 120 | encoding: 'utf8' 121 | }) 122 | assert.equal(outputText.trim(), expectedText.trim()) 123 | } 124 | }) 125 | it('should output right css text with enableFontSetting and custom output', function() { 126 | var srcPath = path.join(__dirname, 'source.css') 127 | var srcText = fs.readFileSync(srcPath, { 128 | encoding: 'utf8' 129 | }) 130 | var fontGear = [-1, 0, 1, 2, 3, 4] 131 | var outputCSSFile = function(gear, clonedRoot) { 132 | gear !== undefined && fs.writeFileSync(path.join(__dirname, 'customFile/fontGear_' + gear +'.css'), clonedRoot, { 133 | encoding: 'utf8' 134 | }) 135 | } 136 | postcss().use(flexible({ enableFontSetting: true, fontGear: fontGear, outputCSSFile: outputCSSFile })).process(srcText).css 137 | // console.log(outputText) 138 | for (let i = -1, len = fontGear.length - 1; i < len; i++) { 139 | var outputText = fs.readFileSync(path.join(__dirname, 'customFile/fontGear_' + i +'.css'), { 140 | encoding: 'utf8' 141 | }) 142 | var expectedText = fs.readFileSync(path.join(__dirname, 'fontGearSource/fontGear_' + i +'.css'), { 143 | encoding: 'utf8' 144 | }) 145 | assert.equal(outputText.trim(), expectedText.trim()) 146 | } 147 | }) 148 | }) 149 | -------------------------------------------------------------------------------- /test/fontGear/fontGear_-1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="-1"] .selector, [data-dpr="1"][data-fontgear="-1"] .selector2 { 2 | font-size: 14px 3 | } 4 | [data-dpr="2"][data-fontgear="-1"] .selector, [data-dpr="2"][data-fontgear="-1"] .selector2 { 5 | font-size: 28px 6 | } 7 | [data-dpr="3"][data-fontgear="-1"] .selector, [data-dpr="3"][data-fontgear="-1"] .selector2 { 8 | font-size: 42px 9 | } 10 | [data-dpr="1"][data-fontgear="-1"] .selector3 { 11 | padding: 8px 12 | } 13 | [data-dpr="2"][data-fontgear="-1"] .selector3 { 14 | padding: 16px 15 | } 16 | [data-dpr="3"][data-fontgear="-1"] .selector3 { 17 | padding: 24px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="-1"] body { 21 | margin: 8px 22 | } 23 | [data-dpr="2"][data-fontgear="-1"] body { 24 | margin: 16px 25 | } 26 | [data-dpr="3"][data-fontgear="-1"] body { 27 | margin: 24px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="-1"][dir="rtl"] body { 31 | padding: 2px 32 | } 33 | html[data-dpr="2"][data-fontgear="-1"][dir="rtl"] body { 34 | padding: 4px 35 | } 36 | html[data-dpr="3"][data-fontgear="-1"][dir="rtl"] body { 37 | padding: 6px 38 | } -------------------------------------------------------------------------------- /test/fontGear/fontGear_0.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="0"] .selector, [data-dpr="1"][data-fontgear="0"] .selector2 { 2 | font-size: 16px 3 | } 4 | [data-dpr="2"][data-fontgear="0"] .selector, [data-dpr="2"][data-fontgear="0"] .selector2 { 5 | font-size: 32px 6 | } 7 | [data-dpr="3"][data-fontgear="0"] .selector, [data-dpr="3"][data-fontgear="0"] .selector2 { 8 | font-size: 48px 9 | } 10 | [data-dpr="1"][data-fontgear="0"] .selector3 { 11 | padding: 10px 12 | } 13 | [data-dpr="2"][data-fontgear="0"] .selector3 { 14 | padding: 20px 15 | } 16 | [data-dpr="3"][data-fontgear="0"] .selector3 { 17 | padding: 30px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="0"] body { 21 | margin: 10px 22 | } 23 | [data-dpr="2"][data-fontgear="0"] body { 24 | margin: 20px 25 | } 26 | [data-dpr="3"][data-fontgear="0"] body { 27 | margin: 30px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="0"][dir="rtl"] body { 31 | padding: 4px 32 | } 33 | html[data-dpr="2"][data-fontgear="0"][dir="rtl"] body { 34 | padding: 8px 35 | } 36 | html[data-dpr="3"][data-fontgear="0"][dir="rtl"] body { 37 | padding: 12px 38 | } -------------------------------------------------------------------------------- /test/fontGear/fontGear_1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="1"] .selector, [data-dpr="1"][data-fontgear="1"] .selector2 { 2 | font-size: 18px 3 | } 4 | [data-dpr="2"][data-fontgear="1"] .selector, [data-dpr="2"][data-fontgear="1"] .selector2 { 5 | font-size: 36px 6 | } 7 | [data-dpr="3"][data-fontgear="1"] .selector, [data-dpr="3"][data-fontgear="1"] .selector2 { 8 | font-size: 54px 9 | } 10 | [data-dpr="1"][data-fontgear="1"] .selector3 { 11 | padding: 12px 12 | } 13 | [data-dpr="2"][data-fontgear="1"] .selector3 { 14 | padding: 24px 15 | } 16 | [data-dpr="3"][data-fontgear="1"] .selector3 { 17 | padding: 36px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="1"] body { 21 | margin: 12px 22 | } 23 | [data-dpr="2"][data-fontgear="1"] body { 24 | margin: 24px 25 | } 26 | [data-dpr="3"][data-fontgear="1"] body { 27 | margin: 36px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="1"][dir="rtl"] body { 31 | padding: 6px 32 | } 33 | html[data-dpr="2"][data-fontgear="1"][dir="rtl"] body { 34 | padding: 12px 35 | } 36 | html[data-dpr="3"][data-fontgear="1"][dir="rtl"] body { 37 | padding: 18px 38 | } -------------------------------------------------------------------------------- /test/fontGear/fontGear_2.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="2"] .selector, [data-dpr="1"][data-fontgear="2"] .selector2 { 2 | font-size: 20px 3 | } 4 | [data-dpr="2"][data-fontgear="2"] .selector, [data-dpr="2"][data-fontgear="2"] .selector2 { 5 | font-size: 40px 6 | } 7 | [data-dpr="3"][data-fontgear="2"] .selector, [data-dpr="3"][data-fontgear="2"] .selector2 { 8 | font-size: 60px 9 | } 10 | [data-dpr="1"][data-fontgear="2"] .selector3 { 11 | padding: 14px 12 | } 13 | [data-dpr="2"][data-fontgear="2"] .selector3 { 14 | padding: 28px 15 | } 16 | [data-dpr="3"][data-fontgear="2"] .selector3 { 17 | padding: 42px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="2"] body { 21 | margin: 14px 22 | } 23 | [data-dpr="2"][data-fontgear="2"] body { 24 | margin: 28px 25 | } 26 | [data-dpr="3"][data-fontgear="2"] body { 27 | margin: 42px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="2"][dir="rtl"] body { 31 | padding: 8px 32 | } 33 | html[data-dpr="2"][data-fontgear="2"][dir="rtl"] body { 34 | padding: 16px 35 | } 36 | html[data-dpr="3"][data-fontgear="2"][dir="rtl"] body { 37 | padding: 24px 38 | } -------------------------------------------------------------------------------- /test/fontGear/fontGear_3.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="3"] .selector, [data-dpr="1"][data-fontgear="3"] .selector2 { 2 | font-size: 22px 3 | } 4 | [data-dpr="2"][data-fontgear="3"] .selector, [data-dpr="2"][data-fontgear="3"] .selector2 { 5 | font-size: 44px 6 | } 7 | [data-dpr="3"][data-fontgear="3"] .selector, [data-dpr="3"][data-fontgear="3"] .selector2 { 8 | font-size: 66px 9 | } 10 | [data-dpr="1"][data-fontgear="3"] .selector3 { 11 | padding: 16px 12 | } 13 | [data-dpr="2"][data-fontgear="3"] .selector3 { 14 | padding: 32px 15 | } 16 | [data-dpr="3"][data-fontgear="3"] .selector3 { 17 | padding: 48px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="3"] body { 21 | margin: 16px 22 | } 23 | [data-dpr="2"][data-fontgear="3"] body { 24 | margin: 32px 25 | } 26 | [data-dpr="3"][data-fontgear="3"] body { 27 | margin: 48px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="3"][dir="rtl"] body { 31 | padding: 10px 32 | } 33 | html[data-dpr="2"][data-fontgear="3"][dir="rtl"] body { 34 | padding: 20px 35 | } 36 | html[data-dpr="3"][data-fontgear="3"][dir="rtl"] body { 37 | padding: 30px 38 | } -------------------------------------------------------------------------------- /test/fontGear/fontGear_4.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="4"] .selector, [data-dpr="1"][data-fontgear="4"] .selector2 { 2 | font-size: 24px 3 | } 4 | [data-dpr="2"][data-fontgear="4"] .selector, [data-dpr="2"][data-fontgear="4"] .selector2 { 5 | font-size: 48px 6 | } 7 | [data-dpr="3"][data-fontgear="4"] .selector, [data-dpr="3"][data-fontgear="4"] .selector2 { 8 | font-size: 72px 9 | } 10 | [data-dpr="1"][data-fontgear="4"] .selector3 { 11 | padding: 18px 12 | } 13 | [data-dpr="2"][data-fontgear="4"] .selector3 { 14 | padding: 36px 15 | } 16 | [data-dpr="3"][data-fontgear="4"] .selector3 { 17 | padding: 54px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="4"] body { 21 | margin: 18px 22 | } 23 | [data-dpr="2"][data-fontgear="4"] body { 24 | margin: 36px 25 | } 26 | [data-dpr="3"][data-fontgear="4"] body { 27 | margin: 54px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="4"][dir="rtl"] body { 31 | padding: 12px 32 | } 33 | html[data-dpr="2"][data-fontgear="4"][dir="rtl"] body { 34 | padding: 24px 35 | } 36 | html[data-dpr="3"][data-fontgear="4"][dir="rtl"] body { 37 | padding: 36px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_-1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="-1"] .selector, [data-dpr="1"][data-fontgear="-1"] .selector2 { 2 | font-size: 14px 3 | } 4 | [data-dpr="2"][data-fontgear="-1"] .selector, [data-dpr="2"][data-fontgear="-1"] .selector2 { 5 | font-size: 28px 6 | } 7 | [data-dpr="3"][data-fontgear="-1"] .selector, [data-dpr="3"][data-fontgear="-1"] .selector2 { 8 | font-size: 42px 9 | } 10 | [data-dpr="1"][data-fontgear="-1"] .selector3 { 11 | padding: 8px 12 | } 13 | [data-dpr="2"][data-fontgear="-1"] .selector3 { 14 | padding: 16px 15 | } 16 | [data-dpr="3"][data-fontgear="-1"] .selector3 { 17 | padding: 24px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="-1"] body { 21 | margin: 8px 22 | } 23 | [data-dpr="2"][data-fontgear="-1"] body { 24 | margin: 16px 25 | } 26 | [data-dpr="3"][data-fontgear="-1"] body { 27 | margin: 24px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="-1"][dir="rtl"] body { 31 | padding: 2px 32 | } 33 | html[data-dpr="2"][data-fontgear="-1"][dir="rtl"] body { 34 | padding: 4px 35 | } 36 | html[data-dpr="3"][data-fontgear="-1"][dir="rtl"] body { 37 | padding: 6px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_0.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="0"] .selector, [data-dpr="1"][data-fontgear="0"] .selector2 { 2 | font-size: 16px 3 | } 4 | [data-dpr="2"][data-fontgear="0"] .selector, [data-dpr="2"][data-fontgear="0"] .selector2 { 5 | font-size: 32px 6 | } 7 | [data-dpr="3"][data-fontgear="0"] .selector, [data-dpr="3"][data-fontgear="0"] .selector2 { 8 | font-size: 48px 9 | } 10 | [data-dpr="1"][data-fontgear="0"] .selector3 { 11 | padding: 10px 12 | } 13 | [data-dpr="2"][data-fontgear="0"] .selector3 { 14 | padding: 20px 15 | } 16 | [data-dpr="3"][data-fontgear="0"] .selector3 { 17 | padding: 30px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="0"] body { 21 | margin: 10px 22 | } 23 | [data-dpr="2"][data-fontgear="0"] body { 24 | margin: 20px 25 | } 26 | [data-dpr="3"][data-fontgear="0"] body { 27 | margin: 30px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="0"][dir="rtl"] body { 31 | padding: 4px 32 | } 33 | html[data-dpr="2"][data-fontgear="0"][dir="rtl"] body { 34 | padding: 8px 35 | } 36 | html[data-dpr="3"][data-fontgear="0"][dir="rtl"] body { 37 | padding: 12px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="1"] .selector, [data-dpr="1"][data-fontgear="1"] .selector2 { 2 | font-size: 18px 3 | } 4 | [data-dpr="2"][data-fontgear="1"] .selector, [data-dpr="2"][data-fontgear="1"] .selector2 { 5 | font-size: 36px 6 | } 7 | [data-dpr="3"][data-fontgear="1"] .selector, [data-dpr="3"][data-fontgear="1"] .selector2 { 8 | font-size: 54px 9 | } 10 | [data-dpr="1"][data-fontgear="1"] .selector3 { 11 | padding: 12px 12 | } 13 | [data-dpr="2"][data-fontgear="1"] .selector3 { 14 | padding: 24px 15 | } 16 | [data-dpr="3"][data-fontgear="1"] .selector3 { 17 | padding: 36px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="1"] body { 21 | margin: 12px 22 | } 23 | [data-dpr="2"][data-fontgear="1"] body { 24 | margin: 24px 25 | } 26 | [data-dpr="3"][data-fontgear="1"] body { 27 | margin: 36px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="1"][dir="rtl"] body { 31 | padding: 6px 32 | } 33 | html[data-dpr="2"][data-fontgear="1"][dir="rtl"] body { 34 | padding: 12px 35 | } 36 | html[data-dpr="3"][data-fontgear="1"][dir="rtl"] body { 37 | padding: 18px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_2.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="2"] .selector, [data-dpr="1"][data-fontgear="2"] .selector2 { 2 | font-size: 20px 3 | } 4 | [data-dpr="2"][data-fontgear="2"] .selector, [data-dpr="2"][data-fontgear="2"] .selector2 { 5 | font-size: 40px 6 | } 7 | [data-dpr="3"][data-fontgear="2"] .selector, [data-dpr="3"][data-fontgear="2"] .selector2 { 8 | font-size: 60px 9 | } 10 | [data-dpr="1"][data-fontgear="2"] .selector3 { 11 | padding: 14px 12 | } 13 | [data-dpr="2"][data-fontgear="2"] .selector3 { 14 | padding: 28px 15 | } 16 | [data-dpr="3"][data-fontgear="2"] .selector3 { 17 | padding: 42px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="2"] body { 21 | margin: 14px 22 | } 23 | [data-dpr="2"][data-fontgear="2"] body { 24 | margin: 28px 25 | } 26 | [data-dpr="3"][data-fontgear="2"] body { 27 | margin: 42px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="2"][dir="rtl"] body { 31 | padding: 8px 32 | } 33 | html[data-dpr="2"][data-fontgear="2"][dir="rtl"] body { 34 | padding: 16px 35 | } 36 | html[data-dpr="3"][data-fontgear="2"][dir="rtl"] body { 37 | padding: 24px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_3.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="3"] .selector, [data-dpr="1"][data-fontgear="3"] .selector2 { 2 | font-size: 22px 3 | } 4 | [data-dpr="2"][data-fontgear="3"] .selector, [data-dpr="2"][data-fontgear="3"] .selector2 { 5 | font-size: 44px 6 | } 7 | [data-dpr="3"][data-fontgear="3"] .selector, [data-dpr="3"][data-fontgear="3"] .selector2 { 8 | font-size: 66px 9 | } 10 | [data-dpr="1"][data-fontgear="3"] .selector3 { 11 | padding: 16px 12 | } 13 | [data-dpr="2"][data-fontgear="3"] .selector3 { 14 | padding: 32px 15 | } 16 | [data-dpr="3"][data-fontgear="3"] .selector3 { 17 | padding: 48px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="3"] body { 21 | margin: 16px 22 | } 23 | [data-dpr="2"][data-fontgear="3"] body { 24 | margin: 32px 25 | } 26 | [data-dpr="3"][data-fontgear="3"] body { 27 | margin: 48px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="3"][dir="rtl"] body { 31 | padding: 10px 32 | } 33 | html[data-dpr="2"][data-fontgear="3"][dir="rtl"] body { 34 | padding: 20px 35 | } 36 | html[data-dpr="3"][data-fontgear="3"][dir="rtl"] body { 37 | padding: 30px 38 | } -------------------------------------------------------------------------------- /test/fontGearCustom/fontGear_4.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="4"] .selector, [data-dpr="1"][data-fontgear="4"] .selector2 { 2 | font-size: 24px 3 | } 4 | [data-dpr="2"][data-fontgear="4"] .selector, [data-dpr="2"][data-fontgear="4"] .selector2 { 5 | font-size: 48px 6 | } 7 | [data-dpr="3"][data-fontgear="4"] .selector, [data-dpr="3"][data-fontgear="4"] .selector2 { 8 | font-size: 72px 9 | } 10 | [data-dpr="1"][data-fontgear="4"] .selector3 { 11 | padding: 18px 12 | } 13 | [data-dpr="2"][data-fontgear="4"] .selector3 { 14 | padding: 36px 15 | } 16 | [data-dpr="3"][data-fontgear="4"] .selector3 { 17 | padding: 54px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="4"] body { 21 | margin: 18px 22 | } 23 | [data-dpr="2"][data-fontgear="4"] body { 24 | margin: 36px 25 | } 26 | [data-dpr="3"][data-fontgear="4"] body { 27 | margin: 54px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="4"][dir="rtl"] body { 31 | padding: 12px 32 | } 33 | html[data-dpr="2"][data-fontgear="4"][dir="rtl"] body { 34 | padding: 24px 35 | } 36 | html[data-dpr="3"][data-fontgear="4"][dir="rtl"] body { 37 | padding: 36px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_-1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="-1"] .selector, [data-dpr="1"][data-fontgear="-1"] .selector2 { 2 | font-size: 15px 3 | } 4 | [data-dpr="2"][data-fontgear="-1"] .selector, [data-dpr="2"][data-fontgear="-1"] .selector2 { 5 | font-size: 30px 6 | } 7 | [data-dpr="3"][data-fontgear="-1"] .selector, [data-dpr="3"][data-fontgear="-1"] .selector2 { 8 | font-size: 45px 9 | } 10 | [data-dpr="1"][data-fontgear="-1"] .selector3 { 11 | padding: 9px 12 | } 13 | [data-dpr="2"][data-fontgear="-1"] .selector3 { 14 | padding: 18px 15 | } 16 | [data-dpr="3"][data-fontgear="-1"] .selector3 { 17 | padding: 27px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="-1"] body { 21 | margin: 9px 22 | } 23 | [data-dpr="2"][data-fontgear="-1"] body { 24 | margin: 18px 25 | } 26 | [data-dpr="3"][data-fontgear="-1"] body { 27 | margin: 27px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="-1"][dir="rtl"] body { 31 | padding: 3px 32 | } 33 | html[data-dpr="2"][data-fontgear="-1"][dir="rtl"] body { 34 | padding: 6px 35 | } 36 | html[data-dpr="3"][data-fontgear="-1"][dir="rtl"] body { 37 | padding: 9px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_0.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="0"] .selector, [data-dpr="1"][data-fontgear="0"] .selector2 { 2 | font-size: 16px 3 | } 4 | [data-dpr="2"][data-fontgear="0"] .selector, [data-dpr="2"][data-fontgear="0"] .selector2 { 5 | font-size: 32px 6 | } 7 | [data-dpr="3"][data-fontgear="0"] .selector, [data-dpr="3"][data-fontgear="0"] .selector2 { 8 | font-size: 48px 9 | } 10 | [data-dpr="1"][data-fontgear="0"] .selector3 { 11 | padding: 10px 12 | } 13 | [data-dpr="2"][data-fontgear="0"] .selector3 { 14 | padding: 20px 15 | } 16 | [data-dpr="3"][data-fontgear="0"] .selector3 { 17 | padding: 30px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="0"] body { 21 | margin: 10px 22 | } 23 | [data-dpr="2"][data-fontgear="0"] body { 24 | margin: 20px 25 | } 26 | [data-dpr="3"][data-fontgear="0"] body { 27 | margin: 30px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="0"][dir="rtl"] body { 31 | padding: 4px 32 | } 33 | html[data-dpr="2"][data-fontgear="0"][dir="rtl"] body { 34 | padding: 8px 35 | } 36 | html[data-dpr="3"][data-fontgear="0"][dir="rtl"] body { 37 | padding: 12px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_1.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="1"] .selector, [data-dpr="1"][data-fontgear="1"] .selector2 { 2 | font-size: 17px 3 | } 4 | [data-dpr="2"][data-fontgear="1"] .selector, [data-dpr="2"][data-fontgear="1"] .selector2 { 5 | font-size: 34px 6 | } 7 | [data-dpr="3"][data-fontgear="1"] .selector, [data-dpr="3"][data-fontgear="1"] .selector2 { 8 | font-size: 51px 9 | } 10 | [data-dpr="1"][data-fontgear="1"] .selector3 { 11 | padding: 11px 12 | } 13 | [data-dpr="2"][data-fontgear="1"] .selector3 { 14 | padding: 22px 15 | } 16 | [data-dpr="3"][data-fontgear="1"] .selector3 { 17 | padding: 33px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="1"] body { 21 | margin: 11px 22 | } 23 | [data-dpr="2"][data-fontgear="1"] body { 24 | margin: 22px 25 | } 26 | [data-dpr="3"][data-fontgear="1"] body { 27 | margin: 33px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="1"][dir="rtl"] body { 31 | padding: 5px 32 | } 33 | html[data-dpr="2"][data-fontgear="1"][dir="rtl"] body { 34 | padding: 10px 35 | } 36 | html[data-dpr="3"][data-fontgear="1"][dir="rtl"] body { 37 | padding: 15px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_2.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="2"] .selector, [data-dpr="1"][data-fontgear="2"] .selector2 { 2 | font-size: 18px 3 | } 4 | [data-dpr="2"][data-fontgear="2"] .selector, [data-dpr="2"][data-fontgear="2"] .selector2 { 5 | font-size: 36px 6 | } 7 | [data-dpr="3"][data-fontgear="2"] .selector, [data-dpr="3"][data-fontgear="2"] .selector2 { 8 | font-size: 54px 9 | } 10 | [data-dpr="1"][data-fontgear="2"] .selector3 { 11 | padding: 12px 12 | } 13 | [data-dpr="2"][data-fontgear="2"] .selector3 { 14 | padding: 24px 15 | } 16 | [data-dpr="3"][data-fontgear="2"] .selector3 { 17 | padding: 36px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="2"] body { 21 | margin: 12px 22 | } 23 | [data-dpr="2"][data-fontgear="2"] body { 24 | margin: 24px 25 | } 26 | [data-dpr="3"][data-fontgear="2"] body { 27 | margin: 36px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="2"][dir="rtl"] body { 31 | padding: 6px 32 | } 33 | html[data-dpr="2"][data-fontgear="2"][dir="rtl"] body { 34 | padding: 12px 35 | } 36 | html[data-dpr="3"][data-fontgear="2"][dir="rtl"] body { 37 | padding: 18px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_3.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="3"] .selector, [data-dpr="1"][data-fontgear="3"] .selector2 { 2 | font-size: 19px 3 | } 4 | [data-dpr="2"][data-fontgear="3"] .selector, [data-dpr="2"][data-fontgear="3"] .selector2 { 5 | font-size: 38px 6 | } 7 | [data-dpr="3"][data-fontgear="3"] .selector, [data-dpr="3"][data-fontgear="3"] .selector2 { 8 | font-size: 57px 9 | } 10 | [data-dpr="1"][data-fontgear="3"] .selector3 { 11 | padding: 13px 12 | } 13 | [data-dpr="2"][data-fontgear="3"] .selector3 { 14 | padding: 26px 15 | } 16 | [data-dpr="3"][data-fontgear="3"] .selector3 { 17 | padding: 39px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="3"] body { 21 | margin: 13px 22 | } 23 | [data-dpr="2"][data-fontgear="3"] body { 24 | margin: 26px 25 | } 26 | [data-dpr="3"][data-fontgear="3"] body { 27 | margin: 39px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="3"][dir="rtl"] body { 31 | padding: 7px 32 | } 33 | html[data-dpr="2"][data-fontgear="3"][dir="rtl"] body { 34 | padding: 14px 35 | } 36 | html[data-dpr="3"][data-fontgear="3"][dir="rtl"] body { 37 | padding: 21px 38 | } -------------------------------------------------------------------------------- /test/fontGearSource/fontGear_4.css: -------------------------------------------------------------------------------- 1 | [data-dpr="1"][data-fontgear="4"] .selector, [data-dpr="1"][data-fontgear="4"] .selector2 { 2 | font-size: 20px 3 | } 4 | [data-dpr="2"][data-fontgear="4"] .selector, [data-dpr="2"][data-fontgear="4"] .selector2 { 5 | font-size: 40px 6 | } 7 | [data-dpr="3"][data-fontgear="4"] .selector, [data-dpr="3"][data-fontgear="4"] .selector2 { 8 | font-size: 60px 9 | } 10 | [data-dpr="1"][data-fontgear="4"] .selector3 { 11 | padding: 14px 12 | } 13 | [data-dpr="2"][data-fontgear="4"] .selector3 { 14 | padding: 28px 15 | } 16 | [data-dpr="3"][data-fontgear="4"] .selector3 { 17 | padding: 42px 18 | } 19 | @media screen and (min-width: 480px) { 20 | [data-dpr="1"][data-fontgear="4"] body { 21 | margin: 14px 22 | } 23 | [data-dpr="2"][data-fontgear="4"] body { 24 | margin: 28px 25 | } 26 | [data-dpr="3"][data-fontgear="4"] body { 27 | margin: 42px 28 | } 29 | } 30 | html[data-dpr="1"][data-fontgear="4"][dir="rtl"] body { 31 | padding: 8px 32 | } 33 | html[data-dpr="2"][data-fontgear="4"][dir="rtl"] body { 34 | padding: 16px 35 | } 36 | html[data-dpr="3"][data-fontgear="4"][dir="rtl"] body { 37 | padding: 24px 38 | } -------------------------------------------------------------------------------- /test/output-custom-2.css: -------------------------------------------------------------------------------- 1 | .selector, 2 | .selector2 { 3 | width: 1rem; 4 | line-height: 3; 5 | } 6 | 7 | [data-dpr="2"] .selector, [data-dpr="2"] .selector2 { 8 | font-size: 32px; 9 | background-image: url(/images/qr@2x.png); 10 | } 11 | 12 | [data-dpr="4"] .selector, [data-dpr="4"] .selector2 { 13 | font-size: 64px; 14 | background-image: url(/images/qr@4x.png); 15 | } 16 | 17 | [data-dpr="2"] .selector3 { 18 | padding: 20px; 19 | } 20 | 21 | [data-dpr="4"] .selector3 { 22 | padding: 40px; 23 | } 24 | 25 | [data-dpr="2"] .selector4 { 26 | background: url(/images/qr@2x.png) 20px 0.266667rem; 27 | } 28 | 29 | [data-dpr="4"] .selector4 { 30 | background: url(/images/qr@4x.png) 40px 0.266667rem; 31 | } 32 | 33 | @media screen and (min-width: 480px) { 34 | [data-dpr="2"] body { 35 | margin: 20px; 36 | } 37 | [data-dpr="4"] body { 38 | margin: 40px; 39 | } 40 | } 41 | 42 | @keyframes c-spinner-snake { 43 | 0% { 44 | transform: rotate(0deg); 45 | } 46 | 47 | to { 48 | transform: rotate(1turn); 49 | } 50 | } 51 | 52 | html[data-dpr="2"][dir="rtl"] body { 53 | padding: 8px; 54 | } 55 | 56 | html[data-dpr="4"][dir="rtl"] body { 57 | padding: 16px; 58 | } 59 | -------------------------------------------------------------------------------- /test/output-custom.css: -------------------------------------------------------------------------------- 1 | .selector, 2 | .selector2 { 3 | width: 1rem; 4 | line-height: 3; 5 | } 6 | 7 | [data-dpr="1"] > .selector, [data-dpr="1"] > .selector2 { 8 | font-size: 16px; 9 | background-image: url(/images/qr@1x.png); 10 | } 11 | 12 | [data-dpr="2"] > .selector, [data-dpr="2"] > .selector2 { 13 | font-size: 32px; 14 | background-image: url(/images/qr@2x.png); 15 | } 16 | 17 | [data-dpr="3"] > .selector, [data-dpr="3"] > .selector2 { 18 | font-size: 48px; 19 | background-image: url(/images/qr@3x.png); 20 | } 21 | 22 | [data-dpr="1"] > .selector3 { 23 | padding: 10px; 24 | } 25 | 26 | [data-dpr="2"] > .selector3 { 27 | padding: 20px; 28 | } 29 | 30 | [data-dpr="3"] > .selector3 { 31 | padding: 30px; 32 | } 33 | 34 | [data-dpr="1"] > .selector4 { 35 | background: url(/images/qr@1x.png) 10px 0.266667rem; 36 | } 37 | 38 | [data-dpr="2"] > .selector4 { 39 | background: url(/images/qr@2x.png) 20px 0.266667rem; 40 | } 41 | 42 | [data-dpr="3"] > .selector4 { 43 | background: url(/images/qr@3x.png) 30px 0.266667rem; 44 | } 45 | 46 | @media screen and (min-width: 480px) { 47 | [data-dpr="1"] > body { 48 | margin: 10px; 49 | } 50 | [data-dpr="2"] > body { 51 | margin: 20px; 52 | } 53 | [data-dpr="3"] > body { 54 | margin: 30px; 55 | } 56 | } 57 | 58 | @keyframes c-spinner-snake { 59 | 0% { 60 | transform: rotate(0deg); 61 | } 62 | 63 | to { 64 | transform: rotate(1turn); 65 | } 66 | } 67 | 68 | [data-dpr="1"] > html[dir="rtl"] body { 69 | padding: 4px; 70 | } 71 | 72 | [data-dpr="2"] > html[dir="rtl"] body { 73 | padding: 8px; 74 | } 75 | 76 | [data-dpr="3"] > html[dir="rtl"] body { 77 | padding: 12px; 78 | } 79 | -------------------------------------------------------------------------------- /test/output-desktop.css: -------------------------------------------------------------------------------- 1 | .selector, 2 | .selector2 { 3 | font-size: 32px; 4 | width: 1rem; 5 | line-height: 3; 6 | background-image: url(/images/qr@2x.png); 7 | } 8 | 9 | .selector3 { 10 | padding: 20px; 11 | } 12 | 13 | .selector4 { 14 | background: url(/images/qr@2x.png) 20px 0.266667rem; 15 | } 16 | 17 | @media screen and (min-width: 480px) { 18 | body { 19 | margin: 20px; 20 | } 21 | } 22 | 23 | @keyframes c-spinner-snake { 24 | 0% { 25 | transform: rotate(0deg); 26 | } 27 | 28 | to { 29 | transform: rotate(1turn); 30 | } 31 | } 32 | 33 | html[dir="rtl"] body { 34 | padding: 8px; 35 | } 36 | -------------------------------------------------------------------------------- /test/output.css: -------------------------------------------------------------------------------- 1 | .selector, 2 | .selector2 { 3 | width: 1rem; 4 | line-height: 3; 5 | } 6 | 7 | [data-dpr="1"] .selector, [data-dpr="1"] .selector2 { 8 | font-size: 16px; 9 | background-image: url(/images/qr@1x.png); 10 | } 11 | 12 | [data-dpr="2"] .selector, [data-dpr="2"] .selector2 { 13 | font-size: 32px; 14 | background-image: url(/images/qr@2x.png); 15 | } 16 | 17 | [data-dpr="3"] .selector, [data-dpr="3"] .selector2 { 18 | font-size: 48px; 19 | background-image: url(/images/qr@3x.png); 20 | } 21 | 22 | [data-dpr="1"] .selector3 { 23 | padding: 10px; 24 | } 25 | 26 | [data-dpr="2"] .selector3 { 27 | padding: 20px; 28 | } 29 | 30 | [data-dpr="3"] .selector3 { 31 | padding: 30px; 32 | } 33 | 34 | [data-dpr="1"] .selector4 { 35 | background: url(/images/qr@1x.png) 10px 0.266667rem; 36 | } 37 | 38 | [data-dpr="2"] .selector4 { 39 | background: url(/images/qr@2x.png) 20px 0.266667rem; 40 | } 41 | 42 | [data-dpr="3"] .selector4 { 43 | background: url(/images/qr@3x.png) 30px 0.266667rem; 44 | } 45 | 46 | @media screen and (min-width: 480px) { 47 | [data-dpr="1"] body { 48 | margin: 10px; 49 | } 50 | [data-dpr="2"] body { 51 | margin: 20px; 52 | } 53 | [data-dpr="3"] body { 54 | margin: 30px; 55 | } 56 | } 57 | 58 | @keyframes c-spinner-snake { 59 | 0% { 60 | transform: rotate(0deg); 61 | } 62 | 63 | to { 64 | transform: rotate(1turn); 65 | } 66 | } 67 | 68 | html[data-dpr="1"][dir="rtl"] body { 69 | padding: 4px; 70 | } 71 | 72 | html[data-dpr="2"][dir="rtl"] body { 73 | padding: 8px; 74 | } 75 | 76 | html[data-dpr="3"][dir="rtl"] body { 77 | padding: 12px; 78 | } 79 | -------------------------------------------------------------------------------- /test/source.css: -------------------------------------------------------------------------------- 1 | .selector, 2 | .selector2 { 3 | font-size: dpr(32px); 4 | width: rem(75px); 5 | line-height: 3; 6 | background-image: url(/images/qr@2x.png); 7 | } 8 | 9 | .selector3 { 10 | padding: dpr(20px); 11 | } 12 | 13 | .selector4 { 14 | background: url(/images/qr@2x.png) dpr(20px) rem(20px); 15 | } 16 | 17 | @media screen and (min-width: 480px) { 18 | body { 19 | margin: dpr(20px); 20 | } 21 | } 22 | 23 | @keyframes c-spinner-snake { 24 | 0% { 25 | transform: rotate(0deg); 26 | } 27 | 28 | to { 29 | transform: rotate(1turn); 30 | } 31 | } 32 | 33 | html[dir="rtl"] body { 34 | padding: dpr(8px); 35 | } 36 | --------------------------------------------------------------------------------